Reading in a string with spaces in C

I am trying to read a line which may or may not include ex spaces. "Hello World". Performing the following steps using the number selection menu that is entered by the user. This is just a small copy of what I'm trying to do.

#include <stdio.h> #include <string.h> int main(void){ char line[3][80]; strcpy(line[0],"default line 1\n"); strcpy(line[1],"default line 2\n"); strcpy(line[2],"default line 3\n"); for(int i = 0; i < 3; i++){ printf("%s", line[i]); } int option = 0; printf("would you like to replace line 1? (1 for yes)\n"); scanf("%d",&option); if(option==1){ printf("what would you like to replace the line with?\n"); fgets(line[0],strlen(line[0]),stdin); } for(int i = 0; i < 3; i++){ printf("%s", line[i]); } } 

Why, after I entered 1, to change the line, it prints a statement asking what I want to replace, and doesn’t enter anything automatically, and then prints the lines with the first empty?

I also tried to read the line with sscanf("%[^\n\t]s", line[0]); no luck. Any ideas?

+6
source share
3 answers

It's because

 scanf("%d",&option); 

leaves the \n character in stdin and is consumed by the first call to fgets() . Therefore, it is best to avoid scanf() in C.

You can fix it with

  scanf("%d",&option); getchar(); /* consume the newline */ 

But I would suggest using fgets() to read an option , and then you can use strtol() to convert it to an integer.

Note that this statement is not what you intended (which limits what you can read in line[0] ).

  fgets(line[0],strlen(line[0]),stdin); 

You probably used:

  fgets(line[0],sizeof line[0],stdin); 

so you can read up to the actual size of line[0] .

Please also read the C Faq entry: http://c-faq.com/stdio/scanfprobs.html

+10
source

Using fgets() usually seems less error prone than obfuscating with scanf() , but if the user enters a string longer than or exceeding the maximum number of specified characters, any additional characters before and including newline remain in the input stream. For this reason, I usually write my own version of gets() to get input strings from the user, and if I want to use numerical input, I use strtol() . Here is an example of such a function:

 char * s_gets(char *st, int n) { char *ret; int ch; ret = fgets(st, n, stdin); if (ret) { while (*st != '\n' && *st != '\0') ++st; if (*st) *st = '\0'; else { while ((ch = getchar()) != '\n' && ch != EOF) continue; // discard extra characters } } return ret; } 

In relation to the OPs problem, I can do something like this:

 #include <stdlib.h> // for strtol() ... char buf[80]; int option = 0; printf("would you like to replace line 1? (1 for yes)\n"); s_gets(buf, sizeof(buf)); option = strtol(buf, NULL, 10); if(option==1){ printf("what would you like to replace the line with?\n"); s_gets(line[0],sizeof(line[0])); } 
+3
source

Your problem is that the '\n' char stays in stdin and is consumed by fgets .

I suggest you always use fgets to read inputs, so

 #include <stdio.h> #include <string.h> #include <stdlib.h> int main(void) { char line[3][80]; char temp[3]; strcpy(line[0],"default line 1\n"); strcpy(line[1],"default line 2\n"); strcpy(line[2],"default line 3\n"); for(int i = 0; i < 3; i++){ printf("%s", line[i]); } int option = 0; printf("would you like to replace line 1? (1 for yes)\n"); fgets(temp,sizeof(temp),stdin); option = atoi(temp); if(option==1){ printf("what would you like to replace the line with?\n"); fgets(line[0],sizeof(line[0]),stdin); } for(int i = 0; i < 3; i++){ printf("%s", line[i]); } } 
+2
source

Source: https://habr.com/ru/post/1012249/


All Articles