Why doesn't scanf("%[^\n]s", text) print output? [closed] - c

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed last year.
Improve this question
char *text;
text = malloc(256);
printf("Enter a sentence:");
scanf("%[^\n]s", text);
printf("%s",text);
Why doesn't the scanf function work in this code?
I don't enter a sentence and immediately the program finished.

scanf("%[^\n]s", text); is worse than gets(). text[] remains unassigned if only "\n" entered *1, possible buffer overflow with no width limit. The s in for format serves no purpose.
Instead use fgets() with its input limit. Check return value.
#define N 256
char *text = malloc(N);
printf("Enter a sentence:");
if (fgets(test, N, stdin)) {
test[strcspn(test, "\n")] = '\0'; // Lop off potential trailing \n
printf("%s\n",text);
}
OP may also have trouble due to a prior scanf() calls that leaves a dangling '\n' in stdin that chokes on this scanf("%[^\n]s".... Avoid using scanf() at all until you know why it is weak.
Sigh - if you must stay with scanf(), use below which 1) uses a leading space to consume all prior white-space like left-over '\n', 2) has a width limit and 3) tests the scanf() success.
if (scanf(" %255[^\n]", text) == 1) { // No 's' in format.
printf("%s\n",text);
}
*1 This explains the "I don't enter a sentence and immediately the program finished." as prior input did not consume a '\n' and OP's code does not either and so stops the scan. Since OP's code did not consume the '\n' and scanf() did not return 1 (which OP's code failed to test), following unposted code certainly fell into undefined behavior.

My guess is that your program runs, but the console closes before you can see the result.
Try to modify to the following:
char *text;
text = malloc(256);
printf("Enter a sentence:");
scanf("%[^\n]s", text);
printf("%s",text);
system("pause");

Related

Why is scanf("%[^\n]s", ...) not capturing a string with spaces?

I've been scouring the globe as to why scanf() is not capturing spaces, and the usual solutions such as "%[^\n]s" or "%100s" (setting string large enough to capture input) have not been working.
The overall goal of my program is to prompt the user to enter a string, and then that string be stored in a .txt file. I don't believe my problem is arising from fprintf(), rather from the initial console scan.
Yes, I am a beginner and do not understand the nuances of C. Apologies for seemingly simple syntactic errors. Here's what I got.
#include <stdio.h>
int main()
{
errno_t inputfile;
FILE *stream;
inputfile = fopen_s(&stream, "inputfile.txt", "w");
printf("%s", "Enter a string. Press ENTER to exit\n");
char c[100];
scanf("%[^\n]s", c);
printf("%100s", c); //using printf() to check if scanf() worked.
//Messing around with specifier to see if problem
//is in printf(), which doesn't seem to be the case.
fprintf(stream, "%s", c);
fprintf(stream, "%s", "ENTER is a correct ending");
fclose(stream);
return 0;
}
Any help is appreciated.
scanf("%[^\n]s", c); is not correct, remove the s at the end of the specifier, you should also use a width limiter to avoid buffer overflow.
It should be:
scanf("%99[^\n]", c); // leave 1 character for the null byte
Notwithstanding, the behavior you describe is unexpected as you can see here:
https://godbolt.org/z/enq93MaG5
Note that I turned your code in a minimal reproducible example, i.e., I removed the unnecessary code, that's what you should do from now on.
Also note that printf("%100s", c); will have the, perhaps undesired, effect of adjusting your string to the right printing the remaining characters as blank spaces to the left, e.g. a string with 10 characters will print 90 blank spaces and then the string.

Why %n in scanf returning 0 when reading a string from console [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
I tried to write a program which takes a line from user (console) until a comma, full stop or newline character is encountered and tell how many characters read following the specific pattern.
The string is read correctly but the count is not accurate.
#include <stdio.h>
int main()
{
int n;
char s[100];
// The following line should read a string until (. or , or new-line in encountered)
// and %n should tell me the no of characters it read until that point
scanf("%[^.,\n]s%n", s, &n);
// The String in okay
printf("%s\n", s);
// But count of characters read is 0
printf("%d\n",n);
return 0;
}
5 problems:
The "s" in "%[^.,\n]s%n" stops scanning as there can be no 's' read after %[^.,\n]. %[^.,\n] would have read in all 's'. Thus the later "%n" never occurred and the n that was later printed, a 0, was bad code - printing the uninitialized n - which could have been any int or a trap.
Scan lacks a width limit. Bad things happen after the 99th character.
With scanf("%[^.,\n]s%n", s, &n);, scanning will saving nothing in s if the first character is a .,\n. Later printing of s is bad as s[] is uninitialized.
Code fails to check the return value of scanf().
scanf() does not certainly read a line as directed with "write a program which takes a line from user" - it stops short using scanf().
C Std Lib defines a line as below, so code should attempt to read the entire line.
A text stream is an ordered sequence of characters composed into lines, each line consisting of zero or more characters plus a terminating new-line character.
scanf() alternative
int n = 0;
char s[100];
s[0] = '\0';
int cnt == scanf("%99[^.,\n]%n", s, &n);
if (cnt == EOF) puts("Nothing was read");
else printf("%s\n", s);
Better alternative
I'd recommend using fgets() instead of scanf(): takes a line from user.
char s[100];
if (fgets(s, sizeof s, stdin)) {
size_t n = strcspn(s, ".,\n"); // offset of string that does not have .,\n
s[n] = '\0';
printf("%s\n", s);
printf("%zu\n", n);
}
Note: Lines longer than about 100 need additional code.

Entering two strings using scanf function [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
How can enter two strings with scanf in C?, I want to use them as follow:
#include <stdio.h>
#include <string.h>
main()
{
char kid[25];
char color[10];
scanf( "%24[^\n]", kid); // kid name
scanf( "%9[^\n]", color);
printf("%s\'s favorite color is %s.\n", kid, color);
return 0;
}
You are reading input till a \n into kid with the first scanf(). But that scanf() won't read the \n and it will remain in the input buffer.
When the next scanf() is done, the first character it sees is the \n upon which it stops reading before anything is written to color.
You could do
scanf("%24[^\n] ", kid);
scanf("%9[^\n]", color);
The space after the [^\n] will read a white-space character like \n.
If %*c is used like
scanf("%24[^\n]%*c", kid);
%*c in scanf() will cause a character to be read but it won't be assigned anywhere. * is the assignment suppressing character. See here.
But if exactly 25 characters are given as input before a \n, the %*c will just read the last character leaving the \n still in the input buffer.
If you can use a function other than scanf(), fgets() would do well.
Do
fgets(kid, sizeof(kid), stdin);
but remember that fgets() would read the \n as well into kid. You could remove it like
kid[strlen(kid)-1]='\0';
Due to this \n being read, the number characters that are read will be effectively 1 less.
Your problem is that this line does not read the \n character from the stream.
scanf( "%24[^\n]", kid); // kid name
So you read the kids name but don't remove the newline character. So the next scanf() just sees a return character on the input stream and thus you will get an empty color.
if (scanf( "%24[^\n]", kid) == 1) { // kid name
char term;
while ( scanf( "%c", &term) == 1 && term != '\n') {
/* read characters until you can't read or you reach the end of line */
}
}
else {
/* Error */
}
If the user input a kids name longer than 24 characters then you need to read and throw away these characters (or do some appropriate error handling). The end of the kids name is marked by the '\n' character.
Note: The while loop above is for illustration purposes. There are better way.
if (scanf( "%24[^\n]", kid) == 1) { // kid name
scanf("%*[^\n]"); // Note. You can not use "%*[^\n]\n". This will fail if just a newline
scanf("\n"); // So split into two lines (the first may read nothing).
}
else {
/* Error */
}

C program gives strange results [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I just started programming and came up with a program to count the number of characters in an input.
The code is as below:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
int number = 0;
int counter = 0;
char sentence[20];
printf("Enter a sentence: ");
scanf("%s", sentence);
while ( sentence[number] != '\n' )
{
counter += 1;
number += 1;
}
printf("no. of characters in sentence you just typed: %d", counter);
return 1;
}
This program has a strange behavior that I cannot understand. It compiles without error but no matter how many characters I type or what character is entered, it shows the no. of characters as 817.
I am curious as to why 817? It's really weird. Also please enlighten me on how I can improve my code since it did not perform as expected.
scanf reads input till \n but not including it So :
while ( sentence[number] != '\n' ) // always true for legal array bound
will lead to illegal memory access, causing undefined behavior. If you do wish to read the string including the [ white-space ] characters, use [ fgets ].
If you wish to count the number of characters, change the while loop to
while ( sentence[number] != '\0' )
scanf with the argument "%s" reads one word, up to the first space or tab or newline, and will not include any \n character in the input. Your loop will never end. Or, more accurately, it will give what the C standard calls "undefined behaviour". In practice, it means that it will keep looping until it either finds a newline somewhere in memory (perhaps 817 places from the start!), or reaches the end of allocated memory and crashes.
If you read the manual page the function scanf does not read white space.
Perhaps fgets would be a better choice along with changing the while loop to
while (sentence[number] != 0 && sentence[number] != '\n')
Just change this line :
while ( sentence[number] != '\n' )
to
while ( sentence[number] != '\0' )
and return 0 at the end
Here is a better version of code to count the number of characters
#include <stdio.h>
main(){
double c;
for(n=0; getchar() != EOF; ++n);
printf("%.0f\n", n);
}

C first fgets() is being skipped while the second runs [duplicate]

This question already has answers here:
Using scanf and fgets in the same program?
(4 answers)
Closed 7 years ago.
The question is:
Why does the first fgets statement is being skipped?
I read somewhere that it might be because of SCANF() that I used before.
I am trying to figure it out but I can't.
Can someone give me the solution (I should probably re-write the first bit of code to avoid scanf, but how?).
This in the code I am struggling with:
for(;;)
{
//Ask if the user wants to add another CD - Y/N
fputs("\nWould you like to enter new CDs details? y or n\n", stdout);
scanf(" %c" ,&type);
if (toupper(type) != 'Y')
break;
puts("");
//getting in the album information
printf("\tLets enter the details of the CD %d:\n\n", count + 1);
fputs("Title?\n", stdout);
//this fgets statement is being skipped
fgets(title[count], sizeof title[count], stdin);
title[count][strlen(title[count]) - 1] = '\0';
fputs("Atrist? \n", stdout);
fgets(artist[count], sizeof artist[count], stdin);
artist[count][strlen(artist[count]) - 1] = '\0';
}
This is because the last ENTER keypress, which causes a newline is left in the input buffer. This is picked up by the first fgets().
You can add a while(getchar() != '\n'); before the first fegts() to avoid this.
[EDIT: Or, for better, as mentioned by Chux Thanks to him in below comment,use something like
int ch; while((ch = getchar()) != '\n' && ch != EOF);
to handle the 'newline' as well as EOF.]
That said, it is never a good choice to mix scanf() and fgets(). Use fgets() always, it is possible and better.
Yes, it's because your scanf() didn't read more than a single character, but the user pressed return. The return remains in the input buffer, so fgets() immediately sees that and returns.
Don't mix them, use only fgets().
Simply change
scanf(" %c" ,&type);
to
scanf(" %c%*c" ,&type);
The reason that the first fgets gets skipped is that your scanf leaves a newline character in the stdin. fgets sees this character and consumes it, thus not waiting for furthur input.
The %*c tells scanf to read and discard a character.

Resources