C Caesar Cipher Function Call Not Behaving as Expected
I am trying to build a program that will do a simple caesar cipher on a text file with single strings with no spaces on each line. For some reason, my cipher function is not shifting text and I am cutting off the strings at various lengths of characters. Can you see where I am messing up with my function call in the while loop?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define FILE_NAME "./infile.txt"
void caeser (char * ch, int shift)
int i = 0;
int len = strlen(ch);
while (ch[i] < len)
if (islower(ch[i]))
ch[i] = ((ch[i] - 'a' + shift) % 26 + 'a');
else
ch[i] = ((ch[i] - 'A' + shift) % 26 + 'A');
i++;
printf("Caesar Cipher = %sn", ch);
int main(void)
char * c = malloc( sizeof(char) * 1000);
FILE* fp = fopen (FILE_NAME, "r");
if (fp == NULL)
printf("Can't open %sn", FILE_NAME);
exit(EXIT_FAILURE);
while(fgets(c, sizeof(c), fp) != 0)
printf("%sn", c);
caeser(c, 1);
fclose(fp);
fp = NULL;
return 0;
c arrays function char caesar-cipher
add a comment |
I am trying to build a program that will do a simple caesar cipher on a text file with single strings with no spaces on each line. For some reason, my cipher function is not shifting text and I am cutting off the strings at various lengths of characters. Can you see where I am messing up with my function call in the while loop?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define FILE_NAME "./infile.txt"
void caeser (char * ch, int shift)
int i = 0;
int len = strlen(ch);
while (ch[i] < len)
if (islower(ch[i]))
ch[i] = ((ch[i] - 'a' + shift) % 26 + 'a');
else
ch[i] = ((ch[i] - 'A' + shift) % 26 + 'A');
i++;
printf("Caesar Cipher = %sn", ch);
int main(void)
char * c = malloc( sizeof(char) * 1000);
FILE* fp = fopen (FILE_NAME, "r");
if (fp == NULL)
printf("Can't open %sn", FILE_NAME);
exit(EXIT_FAILURE);
while(fgets(c, sizeof(c), fp) != 0)
printf("%sn", c);
caeser(c, 1);
fclose(fp);
fp = NULL;
return 0;
c arrays function char caesar-cipher
1
Ouch! Thefgets(c, sizeof(c), stdin)
thing works only ifc
is a local array defined like so:char c[1000]
. In your case, where you allocate memory, you must specify the allocated length:fgets(c, 1000, stdin)
. (That's becausesizeof(c)
is the size of a pointer, usually 4 or 8.)
– M Oehm
Nov 11 at 18:24
The while loop condition seems... odd. Also, ` }i++;` is outside the while loop.
– kfx
Nov 11 at 18:24
1
This resource may be helpful: ericlippert.com/2014/03/05/how-to-debug-small-programs
– kfx
Nov 11 at 18:25
add a comment |
I am trying to build a program that will do a simple caesar cipher on a text file with single strings with no spaces on each line. For some reason, my cipher function is not shifting text and I am cutting off the strings at various lengths of characters. Can you see where I am messing up with my function call in the while loop?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define FILE_NAME "./infile.txt"
void caeser (char * ch, int shift)
int i = 0;
int len = strlen(ch);
while (ch[i] < len)
if (islower(ch[i]))
ch[i] = ((ch[i] - 'a' + shift) % 26 + 'a');
else
ch[i] = ((ch[i] - 'A' + shift) % 26 + 'A');
i++;
printf("Caesar Cipher = %sn", ch);
int main(void)
char * c = malloc( sizeof(char) * 1000);
FILE* fp = fopen (FILE_NAME, "r");
if (fp == NULL)
printf("Can't open %sn", FILE_NAME);
exit(EXIT_FAILURE);
while(fgets(c, sizeof(c), fp) != 0)
printf("%sn", c);
caeser(c, 1);
fclose(fp);
fp = NULL;
return 0;
c arrays function char caesar-cipher
I am trying to build a program that will do a simple caesar cipher on a text file with single strings with no spaces on each line. For some reason, my cipher function is not shifting text and I am cutting off the strings at various lengths of characters. Can you see where I am messing up with my function call in the while loop?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define FILE_NAME "./infile.txt"
void caeser (char * ch, int shift)
int i = 0;
int len = strlen(ch);
while (ch[i] < len)
if (islower(ch[i]))
ch[i] = ((ch[i] - 'a' + shift) % 26 + 'a');
else
ch[i] = ((ch[i] - 'A' + shift) % 26 + 'A');
i++;
printf("Caesar Cipher = %sn", ch);
int main(void)
char * c = malloc( sizeof(char) * 1000);
FILE* fp = fopen (FILE_NAME, "r");
if (fp == NULL)
printf("Can't open %sn", FILE_NAME);
exit(EXIT_FAILURE);
while(fgets(c, sizeof(c), fp) != 0)
printf("%sn", c);
caeser(c, 1);
fclose(fp);
fp = NULL;
return 0;
c arrays function char caesar-cipher
c arrays function char caesar-cipher
asked Nov 11 at 18:20
efuddy
355
355
1
Ouch! Thefgets(c, sizeof(c), stdin)
thing works only ifc
is a local array defined like so:char c[1000]
. In your case, where you allocate memory, you must specify the allocated length:fgets(c, 1000, stdin)
. (That's becausesizeof(c)
is the size of a pointer, usually 4 or 8.)
– M Oehm
Nov 11 at 18:24
The while loop condition seems... odd. Also, ` }i++;` is outside the while loop.
– kfx
Nov 11 at 18:24
1
This resource may be helpful: ericlippert.com/2014/03/05/how-to-debug-small-programs
– kfx
Nov 11 at 18:25
add a comment |
1
Ouch! Thefgets(c, sizeof(c), stdin)
thing works only ifc
is a local array defined like so:char c[1000]
. In your case, where you allocate memory, you must specify the allocated length:fgets(c, 1000, stdin)
. (That's becausesizeof(c)
is the size of a pointer, usually 4 or 8.)
– M Oehm
Nov 11 at 18:24
The while loop condition seems... odd. Also, ` }i++;` is outside the while loop.
– kfx
Nov 11 at 18:24
1
This resource may be helpful: ericlippert.com/2014/03/05/how-to-debug-small-programs
– kfx
Nov 11 at 18:25
1
1
Ouch! The
fgets(c, sizeof(c), stdin)
thing works only if c
is a local array defined like so: char c[1000]
. In your case, where you allocate memory, you must specify the allocated length: fgets(c, 1000, stdin)
. (That's because sizeof(c)
is the size of a pointer, usually 4 or 8.)– M Oehm
Nov 11 at 18:24
Ouch! The
fgets(c, sizeof(c), stdin)
thing works only if c
is a local array defined like so: char c[1000]
. In your case, where you allocate memory, you must specify the allocated length: fgets(c, 1000, stdin)
. (That's because sizeof(c)
is the size of a pointer, usually 4 or 8.)– M Oehm
Nov 11 at 18:24
The while loop condition seems... odd. Also, ` }i++;` is outside the while loop.
– kfx
Nov 11 at 18:24
The while loop condition seems... odd. Also, ` }i++;` is outside the while loop.
– kfx
Nov 11 at 18:24
1
1
This resource may be helpful: ericlippert.com/2014/03/05/how-to-debug-small-programs
– kfx
Nov 11 at 18:25
This resource may be helpful: ericlippert.com/2014/03/05/how-to-debug-small-programs
– kfx
Nov 11 at 18:25
add a comment |
2 Answers
2
active
oldest
votes
I made a few changes in your code and I marked them in bold.
Array start from 0 and the end is the n-1 character.
you checked if ch[i] < len.
ch[i] is a character in the i place of an array, not a number.
in each iteration, you need to increment i by 1. so you can get the next character.
for better design try to sand a printable format to the main function instead print in the function. you should return a pointer to string and print it in main.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define FILE_NAME "./infile.txt"
void caeser (char * ch, int shift)
int i = 0;
int len = strlen(ch);
while (**i < len-1**)
if (islower(ch[i]))
ch[i] = ((ch[i] - 'a' + shift) % 26 + 'a');
**i++;**
else
ch[i] = ((ch[i] - 'A' + shift) % 26 + 'A');
**i++;**
printf("Caesar Cipher = %sn", ch);
int main(void)
char * c = malloc( sizeof(char) * 1000);
FILE* fp = fopen (FILE_NAME, "r");
if (fp == NULL)
printf("Can't open %sn", FILE_NAME);
exit(EXIT_FAILURE);
while(fgets(c, sizeof(c), fp) != 0)
printf("%sn", c);
caeser(c, 1);
fclose(fp);
fp = NULL;
return 0;
*
means something in C so it is not a good idea to try to mark lines as you did. Instead, post code that can be compiled without modification, and you can either describe the changes afterwards, or use code comments
– M.M
Nov 12 at 5:43
while(fgets(c, sizeof(c), fp) != 0)
is incorrect.c
is a pointer,sizeof(c)
is the size of a pointer
– M.M
Nov 12 at 5:44
add a comment |
Note that fgets
may return a "new line character" ('n'
) at the end of the string. You may want to remove the new line character from the buffer.
If the string has blank spaces, 'n'
character, or any characters not in the range A-Z or a-z, then ignore those characters because they don't fit the logic for caeser cipher.
char * c = malloc( sizeof(char) * 1000);
while(fgets(c, sizeof(c), fp) != 0) ...
As mentioned in comments, c
is a pointer and sizeof(c)
is usually 4 or 8 in this case. So you are telling fgets
to read a maximum of 4 or 8 bytes. But each line in the file could be much longer. If you had declared, lets say char c[1000];
then sizeof(c)
would be 1000
. Otherwise don't use sizeof
operator here.
while(i < len) ...i++;
You want to got to the end of the string, and increment inside the loop, so change the condition to:
while(i < len) ... i++;
Lastly, c
or ch
is usually used to denotes a character. This is informal and doesn't really matter, but it's more clear to use buf
or str
if you are declaring a string.
Example:
void caeser(char *buf, int shift)
int i = 0;
int len = strlen(buf);
while(i < len)
char c = buf[i];
if(c >= 'a' && c <= 'z')
buf[i] = (c - 'a' + shift) % 26 + 'a';
else if(c >= 'A' && c <= 'Z')
buf[i] = (c - 'A' + shift) % 26 + 'A';
//else, do nothing if chararacter is not between a-z or A-Z
i++;
int main(void)
FILE* fp = fopen(FILE_NAME, "r");
if(fp == NULL)
printf("Can't open %sn", FILE_NAME);
exit(EXIT_FAILURE);
int buf_size = 1000;
char *buf = malloc(sizeof(char) * buf_size);
while(fgets(buf, buf_size, fp))
//optional: remove the new line character if any
int len = strlen(buf);
if(len && buf[len - 1] == 'n')
buf[len - 1] = 0;
printf("plain : %sn", buf);
caeser(buf, 1);
printf("cipher: %snn", buf);
//free the buffer allocated with malloc
free(buf);
fclose(fp);
return 0;
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53251785%2fc-caesar-cipher-function-call-not-behaving-as-expected%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
I made a few changes in your code and I marked them in bold.
Array start from 0 and the end is the n-1 character.
you checked if ch[i] < len.
ch[i] is a character in the i place of an array, not a number.
in each iteration, you need to increment i by 1. so you can get the next character.
for better design try to sand a printable format to the main function instead print in the function. you should return a pointer to string and print it in main.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define FILE_NAME "./infile.txt"
void caeser (char * ch, int shift)
int i = 0;
int len = strlen(ch);
while (**i < len-1**)
if (islower(ch[i]))
ch[i] = ((ch[i] - 'a' + shift) % 26 + 'a');
**i++;**
else
ch[i] = ((ch[i] - 'A' + shift) % 26 + 'A');
**i++;**
printf("Caesar Cipher = %sn", ch);
int main(void)
char * c = malloc( sizeof(char) * 1000);
FILE* fp = fopen (FILE_NAME, "r");
if (fp == NULL)
printf("Can't open %sn", FILE_NAME);
exit(EXIT_FAILURE);
while(fgets(c, sizeof(c), fp) != 0)
printf("%sn", c);
caeser(c, 1);
fclose(fp);
fp = NULL;
return 0;
*
means something in C so it is not a good idea to try to mark lines as you did. Instead, post code that can be compiled without modification, and you can either describe the changes afterwards, or use code comments
– M.M
Nov 12 at 5:43
while(fgets(c, sizeof(c), fp) != 0)
is incorrect.c
is a pointer,sizeof(c)
is the size of a pointer
– M.M
Nov 12 at 5:44
add a comment |
I made a few changes in your code and I marked them in bold.
Array start from 0 and the end is the n-1 character.
you checked if ch[i] < len.
ch[i] is a character in the i place of an array, not a number.
in each iteration, you need to increment i by 1. so you can get the next character.
for better design try to sand a printable format to the main function instead print in the function. you should return a pointer to string and print it in main.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define FILE_NAME "./infile.txt"
void caeser (char * ch, int shift)
int i = 0;
int len = strlen(ch);
while (**i < len-1**)
if (islower(ch[i]))
ch[i] = ((ch[i] - 'a' + shift) % 26 + 'a');
**i++;**
else
ch[i] = ((ch[i] - 'A' + shift) % 26 + 'A');
**i++;**
printf("Caesar Cipher = %sn", ch);
int main(void)
char * c = malloc( sizeof(char) * 1000);
FILE* fp = fopen (FILE_NAME, "r");
if (fp == NULL)
printf("Can't open %sn", FILE_NAME);
exit(EXIT_FAILURE);
while(fgets(c, sizeof(c), fp) != 0)
printf("%sn", c);
caeser(c, 1);
fclose(fp);
fp = NULL;
return 0;
*
means something in C so it is not a good idea to try to mark lines as you did. Instead, post code that can be compiled without modification, and you can either describe the changes afterwards, or use code comments
– M.M
Nov 12 at 5:43
while(fgets(c, sizeof(c), fp) != 0)
is incorrect.c
is a pointer,sizeof(c)
is the size of a pointer
– M.M
Nov 12 at 5:44
add a comment |
I made a few changes in your code and I marked them in bold.
Array start from 0 and the end is the n-1 character.
you checked if ch[i] < len.
ch[i] is a character in the i place of an array, not a number.
in each iteration, you need to increment i by 1. so you can get the next character.
for better design try to sand a printable format to the main function instead print in the function. you should return a pointer to string and print it in main.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define FILE_NAME "./infile.txt"
void caeser (char * ch, int shift)
int i = 0;
int len = strlen(ch);
while (**i < len-1**)
if (islower(ch[i]))
ch[i] = ((ch[i] - 'a' + shift) % 26 + 'a');
**i++;**
else
ch[i] = ((ch[i] - 'A' + shift) % 26 + 'A');
**i++;**
printf("Caesar Cipher = %sn", ch);
int main(void)
char * c = malloc( sizeof(char) * 1000);
FILE* fp = fopen (FILE_NAME, "r");
if (fp == NULL)
printf("Can't open %sn", FILE_NAME);
exit(EXIT_FAILURE);
while(fgets(c, sizeof(c), fp) != 0)
printf("%sn", c);
caeser(c, 1);
fclose(fp);
fp = NULL;
return 0;
I made a few changes in your code and I marked them in bold.
Array start from 0 and the end is the n-1 character.
you checked if ch[i] < len.
ch[i] is a character in the i place of an array, not a number.
in each iteration, you need to increment i by 1. so you can get the next character.
for better design try to sand a printable format to the main function instead print in the function. you should return a pointer to string and print it in main.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define FILE_NAME "./infile.txt"
void caeser (char * ch, int shift)
int i = 0;
int len = strlen(ch);
while (**i < len-1**)
if (islower(ch[i]))
ch[i] = ((ch[i] - 'a' + shift) % 26 + 'a');
**i++;**
else
ch[i] = ((ch[i] - 'A' + shift) % 26 + 'A');
**i++;**
printf("Caesar Cipher = %sn", ch);
int main(void)
char * c = malloc( sizeof(char) * 1000);
FILE* fp = fopen (FILE_NAME, "r");
if (fp == NULL)
printf("Can't open %sn", FILE_NAME);
exit(EXIT_FAILURE);
while(fgets(c, sizeof(c), fp) != 0)
printf("%sn", c);
caeser(c, 1);
fclose(fp);
fp = NULL;
return 0;
answered Nov 11 at 19:50
Matan Tal
1
1
*
means something in C so it is not a good idea to try to mark lines as you did. Instead, post code that can be compiled without modification, and you can either describe the changes afterwards, or use code comments
– M.M
Nov 12 at 5:43
while(fgets(c, sizeof(c), fp) != 0)
is incorrect.c
is a pointer,sizeof(c)
is the size of a pointer
– M.M
Nov 12 at 5:44
add a comment |
*
means something in C so it is not a good idea to try to mark lines as you did. Instead, post code that can be compiled without modification, and you can either describe the changes afterwards, or use code comments
– M.M
Nov 12 at 5:43
while(fgets(c, sizeof(c), fp) != 0)
is incorrect.c
is a pointer,sizeof(c)
is the size of a pointer
– M.M
Nov 12 at 5:44
*
means something in C so it is not a good idea to try to mark lines as you did. Instead, post code that can be compiled without modification, and you can either describe the changes afterwards, or use code comments– M.M
Nov 12 at 5:43
*
means something in C so it is not a good idea to try to mark lines as you did. Instead, post code that can be compiled without modification, and you can either describe the changes afterwards, or use code comments– M.M
Nov 12 at 5:43
while(fgets(c, sizeof(c), fp) != 0)
is incorrect. c
is a pointer, sizeof(c)
is the size of a pointer– M.M
Nov 12 at 5:44
while(fgets(c, sizeof(c), fp) != 0)
is incorrect. c
is a pointer, sizeof(c)
is the size of a pointer– M.M
Nov 12 at 5:44
add a comment |
Note that fgets
may return a "new line character" ('n'
) at the end of the string. You may want to remove the new line character from the buffer.
If the string has blank spaces, 'n'
character, or any characters not in the range A-Z or a-z, then ignore those characters because they don't fit the logic for caeser cipher.
char * c = malloc( sizeof(char) * 1000);
while(fgets(c, sizeof(c), fp) != 0) ...
As mentioned in comments, c
is a pointer and sizeof(c)
is usually 4 or 8 in this case. So you are telling fgets
to read a maximum of 4 or 8 bytes. But each line in the file could be much longer. If you had declared, lets say char c[1000];
then sizeof(c)
would be 1000
. Otherwise don't use sizeof
operator here.
while(i < len) ...i++;
You want to got to the end of the string, and increment inside the loop, so change the condition to:
while(i < len) ... i++;
Lastly, c
or ch
is usually used to denotes a character. This is informal and doesn't really matter, but it's more clear to use buf
or str
if you are declaring a string.
Example:
void caeser(char *buf, int shift)
int i = 0;
int len = strlen(buf);
while(i < len)
char c = buf[i];
if(c >= 'a' && c <= 'z')
buf[i] = (c - 'a' + shift) % 26 + 'a';
else if(c >= 'A' && c <= 'Z')
buf[i] = (c - 'A' + shift) % 26 + 'A';
//else, do nothing if chararacter is not between a-z or A-Z
i++;
int main(void)
FILE* fp = fopen(FILE_NAME, "r");
if(fp == NULL)
printf("Can't open %sn", FILE_NAME);
exit(EXIT_FAILURE);
int buf_size = 1000;
char *buf = malloc(sizeof(char) * buf_size);
while(fgets(buf, buf_size, fp))
//optional: remove the new line character if any
int len = strlen(buf);
if(len && buf[len - 1] == 'n')
buf[len - 1] = 0;
printf("plain : %sn", buf);
caeser(buf, 1);
printf("cipher: %snn", buf);
//free the buffer allocated with malloc
free(buf);
fclose(fp);
return 0;
add a comment |
Note that fgets
may return a "new line character" ('n'
) at the end of the string. You may want to remove the new line character from the buffer.
If the string has blank spaces, 'n'
character, or any characters not in the range A-Z or a-z, then ignore those characters because they don't fit the logic for caeser cipher.
char * c = malloc( sizeof(char) * 1000);
while(fgets(c, sizeof(c), fp) != 0) ...
As mentioned in comments, c
is a pointer and sizeof(c)
is usually 4 or 8 in this case. So you are telling fgets
to read a maximum of 4 or 8 bytes. But each line in the file could be much longer. If you had declared, lets say char c[1000];
then sizeof(c)
would be 1000
. Otherwise don't use sizeof
operator here.
while(i < len) ...i++;
You want to got to the end of the string, and increment inside the loop, so change the condition to:
while(i < len) ... i++;
Lastly, c
or ch
is usually used to denotes a character. This is informal and doesn't really matter, but it's more clear to use buf
or str
if you are declaring a string.
Example:
void caeser(char *buf, int shift)
int i = 0;
int len = strlen(buf);
while(i < len)
char c = buf[i];
if(c >= 'a' && c <= 'z')
buf[i] = (c - 'a' + shift) % 26 + 'a';
else if(c >= 'A' && c <= 'Z')
buf[i] = (c - 'A' + shift) % 26 + 'A';
//else, do nothing if chararacter is not between a-z or A-Z
i++;
int main(void)
FILE* fp = fopen(FILE_NAME, "r");
if(fp == NULL)
printf("Can't open %sn", FILE_NAME);
exit(EXIT_FAILURE);
int buf_size = 1000;
char *buf = malloc(sizeof(char) * buf_size);
while(fgets(buf, buf_size, fp))
//optional: remove the new line character if any
int len = strlen(buf);
if(len && buf[len - 1] == 'n')
buf[len - 1] = 0;
printf("plain : %sn", buf);
caeser(buf, 1);
printf("cipher: %snn", buf);
//free the buffer allocated with malloc
free(buf);
fclose(fp);
return 0;
add a comment |
Note that fgets
may return a "new line character" ('n'
) at the end of the string. You may want to remove the new line character from the buffer.
If the string has blank spaces, 'n'
character, or any characters not in the range A-Z or a-z, then ignore those characters because they don't fit the logic for caeser cipher.
char * c = malloc( sizeof(char) * 1000);
while(fgets(c, sizeof(c), fp) != 0) ...
As mentioned in comments, c
is a pointer and sizeof(c)
is usually 4 or 8 in this case. So you are telling fgets
to read a maximum of 4 or 8 bytes. But each line in the file could be much longer. If you had declared, lets say char c[1000];
then sizeof(c)
would be 1000
. Otherwise don't use sizeof
operator here.
while(i < len) ...i++;
You want to got to the end of the string, and increment inside the loop, so change the condition to:
while(i < len) ... i++;
Lastly, c
or ch
is usually used to denotes a character. This is informal and doesn't really matter, but it's more clear to use buf
or str
if you are declaring a string.
Example:
void caeser(char *buf, int shift)
int i = 0;
int len = strlen(buf);
while(i < len)
char c = buf[i];
if(c >= 'a' && c <= 'z')
buf[i] = (c - 'a' + shift) % 26 + 'a';
else if(c >= 'A' && c <= 'Z')
buf[i] = (c - 'A' + shift) % 26 + 'A';
//else, do nothing if chararacter is not between a-z or A-Z
i++;
int main(void)
FILE* fp = fopen(FILE_NAME, "r");
if(fp == NULL)
printf("Can't open %sn", FILE_NAME);
exit(EXIT_FAILURE);
int buf_size = 1000;
char *buf = malloc(sizeof(char) * buf_size);
while(fgets(buf, buf_size, fp))
//optional: remove the new line character if any
int len = strlen(buf);
if(len && buf[len - 1] == 'n')
buf[len - 1] = 0;
printf("plain : %sn", buf);
caeser(buf, 1);
printf("cipher: %snn", buf);
//free the buffer allocated with malloc
free(buf);
fclose(fp);
return 0;
Note that fgets
may return a "new line character" ('n'
) at the end of the string. You may want to remove the new line character from the buffer.
If the string has blank spaces, 'n'
character, or any characters not in the range A-Z or a-z, then ignore those characters because they don't fit the logic for caeser cipher.
char * c = malloc( sizeof(char) * 1000);
while(fgets(c, sizeof(c), fp) != 0) ...
As mentioned in comments, c
is a pointer and sizeof(c)
is usually 4 or 8 in this case. So you are telling fgets
to read a maximum of 4 or 8 bytes. But each line in the file could be much longer. If you had declared, lets say char c[1000];
then sizeof(c)
would be 1000
. Otherwise don't use sizeof
operator here.
while(i < len) ...i++;
You want to got to the end of the string, and increment inside the loop, so change the condition to:
while(i < len) ... i++;
Lastly, c
or ch
is usually used to denotes a character. This is informal and doesn't really matter, but it's more clear to use buf
or str
if you are declaring a string.
Example:
void caeser(char *buf, int shift)
int i = 0;
int len = strlen(buf);
while(i < len)
char c = buf[i];
if(c >= 'a' && c <= 'z')
buf[i] = (c - 'a' + shift) % 26 + 'a';
else if(c >= 'A' && c <= 'Z')
buf[i] = (c - 'A' + shift) % 26 + 'A';
//else, do nothing if chararacter is not between a-z or A-Z
i++;
int main(void)
FILE* fp = fopen(FILE_NAME, "r");
if(fp == NULL)
printf("Can't open %sn", FILE_NAME);
exit(EXIT_FAILURE);
int buf_size = 1000;
char *buf = malloc(sizeof(char) * buf_size);
while(fgets(buf, buf_size, fp))
//optional: remove the new line character if any
int len = strlen(buf);
if(len && buf[len - 1] == 'n')
buf[len - 1] = 0;
printf("plain : %sn", buf);
caeser(buf, 1);
printf("cipher: %snn", buf);
//free the buffer allocated with malloc
free(buf);
fclose(fp);
return 0;
edited Nov 12 at 18:42
answered Nov 12 at 5:09
Barmak Shemirani
20.8k42045
20.8k42045
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53251785%2fc-caesar-cipher-function-call-not-behaving-as-expected%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
Ouch! The
fgets(c, sizeof(c), stdin)
thing works only ifc
is a local array defined like so:char c[1000]
. In your case, where you allocate memory, you must specify the allocated length:fgets(c, 1000, stdin)
. (That's becausesizeof(c)
is the size of a pointer, usually 4 or 8.)– M Oehm
Nov 11 at 18:24
The while loop condition seems... odd. Also, ` }i++;` is outside the while loop.
– kfx
Nov 11 at 18:24
1
This resource may be helpful: ericlippert.com/2014/03/05/how-to-debug-small-programs
– kfx
Nov 11 at 18:25