fgets has more characters that its supposed to - c

Hi I'm trying to use fgets to take the string from stdin and store it in input, then it should compare with an array of words (over 50000 words long taken from a text file) using the strcmp method, but i could never get them to compare for some reason until I found out why here is my code.
char[] text;// <----------array is already full and working at this point I just
char input[24];// thought I'd include this for the memcpy
char check[24]="happ";
fgets(input,24, stdin);
for(int i=0; i < 50000; i++){
memcpy(check, text[i], strlen(input));// this is supposed to get a substring
if(strcmp(check, input) == 0){// this is supposed to auto complete
printf("%s",text[i]);}// say for example 4 letters are inputted the entire
//array will be checked if they have the same letters then that word will be printed
printf("\n %lu %s\n",strlen(check),check);
printf("\n %lu %s\n",strlen(input),input);
if "happ" is inserted it should print out the last letter in the array and its
size which it should be 4 but stdin "5 happ" I thought there might be a \n
at the end of input so i used a temp and got the substring of input at length
strlen(input)-1 but all i got was "6 happ\377" please help I tried researching it but I didnt understand what was wrong with it so I didn't know what to research

I was able to find the answer finally it was a simple fix
int cch=strlen(input-1);
if (cch > 1 && input[cch-1] == '\n')
input[cch-1] = '\0';

Related

Why I cannot access the first read char array after reading a series of others in C?

I wanted to read a phrase and a series of numbers/alphabetic separated by ",". I read the first string then I print it (works fine). I read the first string, read 62 of those series and try to print the first string again and is not working. I tried a lot of methods but none working.
char text[1001];
scanf("%[^\n]", text);
for (int i = 1; i <= 62; i++) {
char alpha[3] = {0}, lit_orig, lit_replace;
scanf("%s", alpha);
lit_orig = alpha[0];
lit_replace = alpha[2];
}
printf("\n%s", text);
Input example:
Example text here!
a,H b,j c,6 d,I e,2 f,R g,5 h,t i,h j,k k,m l,f m,D n,F o,1 p,0 q,c r,G s,n t,N u,e v,B w,r x,U y,p z,A A,8 B,X C,S D,P E,T F,a G,M H,d I,K J,L K,3 L,C M,i N,9 O,E P,w Q,o R,z S,4 T,O U,q V,V W,J X,x Y,Z Z,u 0,l 1,y 2,W 3,s 4,Q 5,g 6,v 7,7 8,b 9,Y
Output example: There is no output.
I did expect it to print just fine the first string called "text" but it is not working. I tried even clearing out the buffer using getchar() but no results (this is what other websites said it would work). Can you explain what is wrong with my code?
Taking into account this code snippet
lit_orig = alpha[0];
lit_replace = alpha[2];
where there is used the index equal to 2 it seems that in the call of scanf
scanf("%s", alpha);
you are entering three characters. As a result the terminating zero character '\0' is written outside the array alpha in the memory occupied by the array text. As a result the array text contains an empty string.
You need to declare the array alpha at least like
char alpha[4] = {0},
And use the format string in the call of scanf the following way
scanf("%3s", alpha);
Your alpha is too small for what you are doing.
Change to char alpha[5] for a quick fix.
Insert an output inside your loop to be aware of what is happening.
printf ("(%4s)", alpha);
Then fine tune your access and use of alpha.
Note the "()" I added to the debug output, to make sure that you see whether/where white space is. I think it might surprise you.

How does this code print the last word the user inputs?

This small piece of code takes a user input and returns the last word from the user input.
I don't exactly understand how those 2 lines of code work
can someone explain why or how printf( &last_word[i]); when I is at position 0 prints the last word of the sentence entered by the user input.
the purpouse of the program is to print the last word of the user input, but I dont understand those lines of code, If I change something on those 2 lines, the code stops working and it doesnt return the last word entered by the user.
#include <stdio.h>
int main(){
int i = 0;
char *last_word;
char str[800];
printf("enter:");
fgets(str,100,stdin);
while (str[i] != '\0') {
if (str[i] == ' ' && str[i + 1] > 32)
last_word = &str[i + 1];
i++;
}
/*------------------------these next lines of code-----------------------*/
/*-----> i = 0;
/*-----> printf( &last_word[i]);
return 0;
}
Holy undefined behavior batman.
The while loop stuffs the address of the next character past a space character into last_word; thus if there are any space characters it points one past the last one.
i = 0 therefore &last_word[i] is the same as last_word. So it uses the last word as a printf format string.
But that's not the same as last word. Try this input: " %n%n%n%n%n%n%n%n". Goodbye.
The first argument to printf should almost always be a constant. You want printf("%s", last_word); In fact, let us put it this way; the only reason to ever not pass a constant format string to printf and friends is your standard library is too old to support %*d for dynamic widths.

I am trying to create a program that takes a name and outputs the initials but keep running into an array error

I am trying to create a program that take the input from the user and prints the first character of each word but every time I try to Here is my code.
#include <stdio.h>
#include <cs50.h>
#include <string.h>
int main(void)
{
char leng[100];
int len;
scanf("%s", &leng[100]);
len = strlen(&leng[100]);
char name[len];
//checking if at end or not
while (name[len] != '\0')
{
if (name[len] == ' ')
printf("%c", name[len + 1]);
len++;
}
}
Every time I give a name it shows an error something like:
index 3 out of bounds for type 'char [len]'
These two lines are incorrect:
scanf("%s", &leng[100]);
len = strlen(&leng[100]);
If you translate these into English, their meanings as written are:
Scan a string to the memory at the address of 101st element of the
leng array.
Get the length of the string that starts at the address
of the 101st element of the leng array.
The array index is out of bounds because leng[100] is past the end of the array. Remember that a 100 element array goes from 0 to 99, not from 1 to 100!
You want to be scanning into the base address of the array, and passing the base address of the array into strlen(). I'll leave the syntax for you to figure out from your textbook.
And by the way, you also have a problem in your code because you're reading your data into an array named leng, but your loop is working with an array named len. There are at least two additional problems in your code, but I'll leave them for you to debug.
There are a few things to consider with your code. As #richardschwartz already mentioned, you are not referencing your char arrays correctly. you have:
scanf("%s", &leng[100]);
len = strlen(&leng[100]);
You may want the following instead:
scanf("%s", leng);
len = strlen(leng);
Also, keep in mind that scanf with the %s flag will stop reading input once white-space is detected. For example, if you input "hello world",
scanf("%s", leng);
will only catch the characters "hello". To get around this, you could loop scanf to read multiple words and return the first character of each word as you desire.
Lastly, scanf is not advised for beginners though. See paxdiablo's excellent reason regarding lack of overflow protection, here: https://stackoverflow.com/a/1248017/6870832

C - Making sure user input is of appropriate length

Something that I thought that would be pretty basic has me stumped.
If I have a char array char menuInput[3]; and do fgets(menuInput,3,stdin);, I can easily check if they entered nothing:
if(menuInput[0]=='\n')
{
printf("******You made no selection.******");
}
Or if they entered too many (in this case, more than one) characters:
else if(menuInput[1]!='\n')
{
printf("******Invalid Selection: Please enter a single digit option.******");
break;
}
In that case, the user is entering either no characters, exactly the right amount (one), or too many.
What is giving me trouble is checking when they could either enter no characters, up to n amount, or too many.
If I have char surname[SURNAME_MAX + 1];, and use fgets(surname,SURNAME_MAX + 1,stdin); where SURNAME_MAX is 12, I can't work out how to check whether the input falls within the 'acceptable' range.
I can easily see if the user has inputted anything at all (if surname[0]='\n') and if they have entered exactly 12 characters (with the 13th being the '\n').
I think the crux of things is here is just making sure that, somewhere, surname[SURNAME_MAX + 1] contains '\n', but I don't know how to do that in C.
Regards,
Doug
EDIT: Ok, I'm going with #R Sahu's answer, but am having trouble making it work properly.
I'm expecting, at most, the 12 characters defined by SURNAME_MAX.
This should mean that, by that answer, my array should be surname[SURNAME_MAX+3] ("need at least SURNAME_MAX+2 just to store the newline and the terminating null character")
Then I fgets(surname,SURNAME_MAX + 3,stdin); and then is it supposed to be:
while(strlen(surname)>SURNAME_MAX+2);
{
printf("Input is too long!\n");
printf("Surname (1-12 characters): ");
fgets(surname,SURNAME_MAX + 2,stdin);
}
?
Is that the correct way of implementing the answer?
It looks right to me, but, no matter what I enter, I'm getting the "Input is too long!" message.
EDIT 2: My bad, had some code in the wrong place, all good now.
You said:
What is giving me trouble is checking when they could either enter no characters, up to n amount, or too many.
My suggestion: If you are expecting to see at most N characters, create an array whose size is larger than N+2. You need at least N+2 just to store the newline and the terminating null character, and use fgets on that string. If the length of the string is greater than N+1, then you know they entered too many characters. Detecting whether they entered too few characters is simple. I think you will be able to figure it out.
For finding character in string, you can use strchr method:
char *pch;
pch=strchr(SURNAME,'\n');
if (pch != NULL)
{
// ok we've got \n in string
}
But I'm not sure it is the best way to solve this problem at all.
Suggest separating user input from variable checking/assignment.
First read in user input
char buf[100];
if (fgets(buf, sizeof buf, stdin) == NULL) {
// EOF or IO error occurred.
return;
}
Now qualify input; various methods exist.
int len = strlen(buf);
// lop off potential \n
if (buf > 0 && buf[len-1] == '\n') buf[--len] = 0;
if (len >= sizeof surname) {
// Input too long
return;
}
memcpy(surname, buf, len + 1);

Replace value in string with another from another string

I've been stuck for a while now. The program i'm writing basically changes the false words with the correct ones from the dictionary. However, when i run the program, it gives me no warnings or errors, but it doesn't display anything. Can you please help me?
#include<stdio.h>
#include<ctype.h>
#include<string.h>
int main(void){
char fname[20],word[2500], dictn[50];
int i,j;
float len1, len2;
FILE *inp, *dict, *outp, *fopen();
fpos_t pos1, pos2;
dict= fopen("dictionary.txt", "r");
printf("Enter the path of the file you want to check:\n");
scanf("%s", fname);
inp= fopen(fname, "r");
for(i=0;(fscanf(inp, "%s", word) != EOF); i++){
for(j=0;fscanf(dict, "%s", dictn) != EOF; j++){
fgetpos(inp, &pos1);
fgetpos(dictn, &pos2);
len1=(float)strlen(word);
len2=(float) strlen(dictn);
if(len1<=(0.6*len2)){
fsetpos(dictn, &pos1);
}
if(strncmp(word, dictn, 1)==0){
fsetpos(dictn, &pos1);
}
if(strcmp(word, dictn)==0){
fsetpos(dictn, &pos1);
}
}
printf("%s ", word);
}
fclose(inp);
fclose(dict);
return(0);
}
You can use
sprintf(word, "%s ", dictn);
If your code is working with printf it should work with sprintf, provided you don't overflow "word", including the NULL termination, so you might have to resize "word" if it is smaller than dictn.
First of all, I'm assuming you have created arrays word and dictn with enough size to hold the maximum length string any of your files.
First fault:
In loops you've created, i represents number of strings in input file and j represents number of strings in dictionary. word is your input string variable and dictn is your dictionary string variable. But you want to retrieve and alter word's ith or dictn's jth character. This may cause an error because there can be a case like this:
Suppose there are 10 words at inp file and 100 words at dictn. And in your loops, i have value of 8 and j have value of 88. Corresponding these i and j values, word has string value of, say, apple and dictn has string value of apple also. So this means apple is the 8th word at input file and 88th word at dictionary file. And if one of those if conditions was satisfied, compiler tries to apply a statement like word[i]=dictn[j];. This means word[8] = dictn[88]; for this example. But both of those string have apple as values which consists only 5 characters! And this will cause an error since you've tried to retrieve 88th character of a 5-length string and assign it to the 8th character of a 5-length string. So your code is wrong, it will only work for some cases which will be a rare situation.
Second fault:
I assume you want to read whole dictionary file for every word in input file but you will be able to read it for only first word of input file since you don't reopen it or set position indicator at the beginning of dictionary file after you read whole dictionary.
Third fault:
Your first if statement will never be reached assuming you have created len1 and len2 variables as integers. Because in your if statement, there is a multiplication of a decimal number and an integer which will return 0 as a result and since fscanf() ignores whitespaces, len1 and len2 will be at least 1.
Fourth fault:
Also your else if statement will never be reached because if a string has same value with another, their first character will also be equal to each other and your if statement where you compare their first characters will be also accepted.
Actually, I would write a code as solution but first of all you need to correct things up which are logically wrong because I do not know what you are really try to achieve by your code -just because I commented with full of assumptions-. But I can provide you some guidelines:
Convert your len1 and len2 variables from int to float and cast values which return from strlen() functions to float.
Reopen your dict file for every iteration of outside loop. (And do not forget not to close it).
To change your inp file, you can use a fpos_t type of variable to track your position indicator of your inp file (fgetpos() to get current position and fsetpos() to change position with value of fpos_t variable. You can search them.) and type the word with fprintf() or fputs() to that location to change that string.

Resources