2
char toFind[100];
char replace[100];
int pos = 0;
printf("Enter a text: ");
scanf("%[^\n]", str);
printf("Enter a search pattern: ");
scanf("%[^\n]", toFind);
printf("Enter a substitute: ");
scanf("%[^\n]", replace);
pos = strnfnd(0, toFind);
strins(pos, replace);
printf("Der Text ist: %s", str);

This code sample let me read the value for str but skips the other two scanf. I have no idea why. What can I do to fix this?

Ps: str is a global char array

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
jonasPamm
  • 87
  • 9

3 Answers3

2

After this call of scanf

scanf("%[^\n]", str);

the new line character '\n' still is present in the input buffer.

So the next call of scanf

scanf("%[^\n]", toFind);

that reads input until the new line character '\n' is encountered reads nothing.

You should write for example

scanf("%[^\n]%*c", str);

to remove the new line character '\n' from the input buffer.

Here is a demonstration program

#include <stdio.h>

int main( void )
{
    char s[100];
    
    scanf( "%99[^\n]%*c", s );
    puts( s );
    
    scanf( "%99[^\n]", s );
    puts( s );

    return 0;
}

In this case if to enter strings for example like

Hello
      World

then the output will be

Hello
      World

Another and more simple approach is to prepend the format string with a blank. For example

scanf(" %[^\n]", toFind);
      ^^^^

In this case all leading white space characters will be skipped.

Here is a demonstration program.

#include <stdio.h>

int main( void )
{
    char s[100];
    
    scanf( "%99[^\n]", s );
    puts( s );
    
    scanf( " %99[^\n]", s );
    puts( s );

    return 0;
}

In this case if to enter strings as shown above that is

Hello
      World

then the program output will be

Hello
World
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

It depends where you run the compiled code - the operating system. In some cases when the "Enter" key is pressed, two bytes are emitted in the input stream (10 and 13) instead of '\n' (10). In that case you need to flush the extra symbols. Check the comments for the exact implementation.

IvanDi
  • 147
  • 2
  • 8
  • 1
    Adding the space will filter *any amount* of whitespace in the input stream (including none). Whether there were 1 or 2 characters for the newline isn't relevant, since OP hasn't flushed any of them. – Weather Vane Oct 26 '21 at 12:28
0

There are problems with your scanf() usage: scanf("%[^\n]", str);

  • you do not specify the maximum number of characters to store into str, hence a sufficiently long line typed by the user will cause undefined behavior. This is a typical software flaw hackers can try and exploit. You can prevent this by specifying the limit as scanf("%99[^\n]", str);

  • you do not read the trailing newline entered by the user, so the next call scanf("%[^\n]", toFind); will fail because no characters different from '\n' are present in the input stream, since the first pending byte is '\n', or EOF.

  • you do not check the return value of the scanf() calls, so you cannot detect input errors such as the above.

  • note however that scanf("%99[^\n]", str); will fail if the user types enter immediately and str will not be modified in this case.

It is much safer to use fgets() instead of scanf() for this task:

char str[100];
char toFind[100];
char replace[100];
int pos = 0;
printf("Enter a text: ");
if (!fgets(str, sizeof str, stdin)) {
    printf("input error\n");
    return 1;
}
str[strcspn(str, "\n")] = '\0'; /* strip the trailing newline if any */
printf("Enter a search pattern: ");
if (!fgets(toFind, sizeof toFind, stdin)) {
    printf("input error\n");
    return 1;
}
toFind[strcspn(toFind, "\n")] = '\0'; /* strip the trailing newline if any */
printf("Enter a substitute: ");
if (!fgets(replace, sizeof replace, stdin)) {
    printf("input error\n");
    return 1;
}
replace[strcspn(replace, "\n")] = '\0'; /* strip the trailing newline if any */
pos = strnfnd(0, toFind);
strins(pos, replace);
printf("Der Text ist: %s\n", str);
chqrlie
  • 131,814
  • 10
  • 121
  • 189