I was asked to do a work in C when I'm supposed to read from input until there's a space and then until the user presses enter.
If I do this:
scanf("%2000s %2000s", a, b);
It will follow the 1st rule but not the 2nd.
If I write:
I am smart
What I get is equivalent to:
a = "I";
b = "am";
But It should be:
a = "I";
b = "am smart";
I already tried:
scanf("%2000s %2000[^\n]\n", a, b);
and
scanf("%2000s %2000[^\0]\0", a, b);
In the 1st one, it waits for the user to press Ctrl+D (to send EOF) and that's not what I want.
In the 2nd one, it won't compile. According to the compiler:
warning: no closing ‘]’ for ‘%[’ format
Any good way to solve this?
scanf (and cousins) have one slightly strange characteristic: white space in (most placed in) the format string matches an arbitrary amount of white space in the input. As it happens, at least in the default "C" locale, a new-line is classified as white space.
This means the trailing '\n' is trying to match not only a new-line, but any succeeding white-space as well. It won't be considered matched until you signal the end of the input, or else enter some non-white space character.
One way to deal with that is something like this:
scanf("%2000s %2000[^\n]%c", a, b, &c);
if (c=='\n')
// we read the whole line
else
// the rest of the line was more than 2000 characters long. `c` contains a
// character from the input, and there's potentially more after that as well.
Depending on the situation, you might also want to check the return value from scanf, which tells you the number of conversions that were successful. In this case, you'd be looking for 3 to indicate that all the conversions were successful.
scanf("%2000s %2000[^\n]", a, b);
use getchar and a while that look like this
while(x = getchar())
{
if(x == '\n'||x == '\0')
do what you need when space or return is detected
else
mystring.append(x)
}
Sorry if I wrote a pseudo-code but I don't work with C language from a while.
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
int main(void)
{
int i = 0;
char *a = (char *) malloc(sizeof(char) * 1024);
while (1) {
scanf("%c", &a[i]);
if (a[i] == '\n') {
break;
}
else {
i++;
}
}
a[i] = '\0';
i = 0;
printf("\n");
while (a[i] != '\0') {
printf("%c", a[i]);
i++;
}
free(a);
getch();
return 0;
}
I am too late, but you can try this approach as well.
#include <stdio.h>
#include <stdlib.h>
int main() {
int i=0, j=0, arr[100];
char temp;
while(scanf("%d%c", &arr[i], &temp)){
i++;
if(temp=='\n'){
break;
}
}
for(j=0; j<i; j++) {
printf("%d ", arr[j]);
}
return 0;
}
#include <stdio.h>
int main()
{
char a[5],b[10];
scanf("%2000s %2000[^\n]s",a,b);
printf("a=%s b=%s",a,b);
}
Just write s in place of \n :)
//increase char array size if u want take more no. of characters.
#include <stdio.h>
int main()
{
char s[10],s1[10];
scanf("\n");//imp for below statement to work
scanf("%[^\n]%c",s);//to take input till the you click enter
scanf("%s",s1);//to take input till a space
printf("%s",s);
printf("%s",s1);
return 0;
}
Related
This question already has answers here:
scanf() leaves the newline character in the buffer
(7 answers)
Closed 2 years ago.
This code says segmentation fault cause the program's scanf isn't working. I used a debugger to find out this. The scanf(num) is skipped. And thus the segmentation fault. Can somebody tell why the scanf is being skipped? I used [^\n] so that scanf can read string with spaces. Help.
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main(void)
{
int a, b;
scanf("%d %d", &a, &b);
int sumr, maxr;
int sumc, maxc;
int white[b + 1];
white[0] = -1;
int ele[b][a];
for (int opl = 0; opl < a; opl++)
{
for (int pl = 0; pl < b; pl++)
{
ele[pl][opl] = 0;
}
}
char num[100000];
int c = -1;
c:
c++;
scanf("%[^\n]%*c", num);
int hu = 0;
int len = strlen(num);
white[b] = len;
for (int ji = 0; ji < len; ji++)
{
if (isspace(num[ji]))
{
white[hu] = ji;
hu++;
}
}
for (int ft = 0; ft < b; ft++)
{
int lopl = 1;
for (int koi = white[ft + 1] - 1; koi > white[ft]; koi--)
{
ele[ft][c] += lopl * (num[koi] - '0');
lopl = lopl * 10;
}
}
if (a > c)
goto c;
}
scanf("%[^\n]%*c", num);
As a first step. you should always check the return value of functions that can adveresely affect your program. In other words, something like:
if (scanf("%d %d", &a, &b) != 2) { handleOneProblem(); }
if (scanf("%[^\n]%*c", num) < 1) { handleAnother(); }
If that second one fails, then num will be left containing whatever arbitrary data it contained before the call, and you probably don't want to then use it as if it contains a valid string.
On top of that, you should be aware that some, but not all, scanf format specifiers will gobble up white space before attempting to read the data. For example, %d will first skip over whitespace and then attempt to read an integer. However, format specifiers such as [ and c will not.
And none of them will gobble up whitespace after the field has been read for the format specifier. That means, if you want that done, you need to do it yourself, with a set of functions like:
#include <stdio.h>
int gobbleLineFile(FILE *inFile) {
int ch;
while ((ch = fgetc(inFile)) != '\n' && ch != EOF) {}
return ch;
}
int gobbleLineStdIn(void) { return gobbleLineFile(stdin); }
As an aside, a lot of problems with scanf are caused by mixing those format specifiers that skip white-space, with those that don't. You can code around that as per above suggestion but, if you're expecting the user to give line-based input, it's often better to do everything as line-based, then use sscanf to break apart the lines.
A fairly decent line-based input routine can be found here.
You have to catch the '\n' that was left from the first scanf.
Either change it to: scanf("%d %d\n", &a, &b);
or put a getchar(); right after it.
Because the next reading: scanf("%[^\n]%*c", num); will read until the next '\n', which is the first thing left on the buffer.
I'm trying to write a program (in C) where the input is reversed and printed in reverse line by line. For the most part, the code actually does just that. The trouble is that for some (most) of my input, I will get a random character or an extra newline in between my input and my output in the console.
For example, I start the program, type "testing" into the console, and get "gnitseT" back after hitting enter. This has happened successfully and is what I expect. It looks like this:
Testing
gnitseT
But then when I type "Hello" into the console, it looks like this:
Hello
g (unexpected)
olleH
Or if I type "running" into the console, instead of getting an unexpected "g" in between my input and output lines, I get an extra newline.
Running
newline here
extra newline here (unexpected)
gninnuR
#include <stdio.h>
void reverse(int length, char s[])
{
int i;
for (i = length; i >= 0; i--)
{
printf("%c", s[i]);
}
printf("\n");
}
int main(void)
{
char smain[2000];
int c;
int i;
i = 0;
while ((c = getchar()) != EOF)
{
smain[i] = c;
i++;
if (c == '\n')
{
reverse(i, smain);
i = 0;
}
}
return 0;
}
The expected behavior is for the program to output into the console the reversed input after the enter key is pressed.
Sometimes, especially at the very beginning of the program, it will work perfectly.
Then, it starts giving me a random character in between my input and output, or it starts giving me an extra newline.
I would like to have it so that it just prints the input in reverse order without any unexpected odd characters showing up in between the input and the output.
Thanks for any help.
Your immediate problem is you are reading and attempting to print one character past the end of the characters stored in your array with
for (i = length; i >= 0; i--) {
printf("%c", s[i]);
}
Why? You add length characters to smain in main(). In C, arrays are zero-based. The characters in your string are from 0 -> length-1 (the nul-character in a string is located at s[length], but here you never add a nul-terminating character, so the value at that index is simply indeterminate). If the element has not been initialized (which it will not be on your first word or any subsequent word equal to or longer than your longest word entered at that time) Undefined Behavior results since you are attempting to read and print an indeterminate value from an uninitialized element in array. How your terminal will output the indeterminate is undefined -- and may well result in a G being printed.
To correct the problem, loop for (i = length - 1; i >= 0; i++) or very simply:
while (length--)
printf ("%c", s[length]);
putchar ('\n'); /* don't printf a single-character */
(note: don't call the variadic printf function to output a single-character, that is what putchar() is for)
Putting it altogether and fixing your logic so you don't add and print the '\n' as part of every word you are reversing, you could do:
#include <stdio.h>
#define MAXC 2048 /* if you need a constant, #define one (or more) */
void reverse(int length, char s[])
{
while (length--)
printf ("%c", s[length]);
putchar ('\n'); /* don't printf a single-character */
}
int main (void) {
char smain[MAXC];
int c, i = 0;
while ((c = getchar()) != EOF) {
if (c == '\n') {
reverse(i, smain);
i = 0;
}
else
smain[i++] = c;
}
if (i) /* protect against file with no POSIX end-of-file */
reverse (i, smain);
return 0;
}
(note: the if {...} else {...} logic to prevent adding the '\n')
Example Use/Output
$ printf "Hello\nGoodbye\n" | ./bin/prnrevlines
olleH
eybdooG
Which will work just as well without the POSIX eof, e.g.
$ printf "Hello\nGoodbye" | ./bin/prnrevlines
olleH
eybdooG
on line 29
++i;
this means "i" now have length+1 so, you have been out of the string, you can change the program to :
#include <stdio.h>
void reverse(int length, char s[])
{
int i;
for (i = length; i >= 0; i--)
{
printf("%c", s[i]);
}
printf("\n");
}
int main(void)
{
char smain[2000];
int c;
int i;
i = 0;
while ((c = getchar()) != EOF)
{
smain[i] = c;
if (c == '\n')
{
reverse(i, smain);
i = 0;
}
else i++;
}
return 0;
}
By using the given source code I am trying to do some arithmetic operations. The given input is:
1
234*34
Since there is no space between 234 and * and 34, scanf is not reading it properly. What should I do so that scanf will read this input and give correct answer without providing the space between the input numbers?
#include <stdio.h>
int arithematic(){
int a,c,t,i=0,k,l;
char b[100];
scanf("%d%s%d",&a,&b[0],&c);
if(b[0] =='+')
t = a+c;
if(b[0] == '-')
t=a-c;
if(b[0]=='*')
t=a*c;
k=a;
l=c;
while(k>0||l>0)
{
k/=10;l/=10;
i++;
}
printf("%d\n",a);
printf("%s",b);
printf("%d\n",c);
while(i>0)
{
printf("-");
i--;
}
printf("\n%d\n",t);
}
int main(void)
{
int n;
scanf("%d",&n);
while(n--)
{
arithematic();
printf("\n");
}
}
Replace scanf("%d%s%d",&a,&b[0],&c); with scanf("%d %1[+-*/]%d",&a,b,&c);. The meaning of %1[+-*/] is to consume exactly one character belonging to the set of the four operators. The space preceding it is to consume optional white spaces.
I'm completely new to programming (1st term in uni) and I can't keep up with my lecturer. At the moment I'm stuck on this exercise (for much more time than I'm willing to admit). I've tried to find help on the internet (in this site and others as well), but I can't, since our lecturer has us use a very simple form of c. I'm not asking necessarily for a complete answer. I'd really appreaciate even some hints about where I'm on the wrong. I understand that it might be really simple for some, that the question might seem ignorant or stupid and I feel bad for not getting what's wrong, but I need to try to understand.
So, what I'm trying to do is use scanf and a do while loop so the user can input characters in an array. But I don't understand why the loop won't stop when the user presses ENTER. There's more to the code, but I'm trying to take it slowly, step by step. (I'm not allowed to use pointers and getchar etc).
#include <stdio.h>
main()
{
char a[50];
int i;
printf("Give max 50 characters\n");
i=0;
do
{
scanf("%c", &a[i]);
i=i+1;
}
while((i<=50) && (a[i-1]!='\0'));
for(i=0; i<50; i++)
printf("%c", a[i]);
}
There aren't any nul-terminated strings here, but only string arrays.
So, when pressing enter, a[i-1] is \n not \0 (scanf with %c as parameter doesn't nul-terminate the strings, and ENTER is just a non-nul character with code 10 AKA \n)
Then don't print the rest of the string because you'll get junk, just reuse i when printing the string back:
#include <stdio.h>
main()
{
char a[50];
int i;
printf("Give max 50 characters\n");
i=0;
do
{
scanf("%c", &a[i]);
i=i+1;
}
while((i<sizeof(a)) && (a[i-1]!='\n')); // \n not \0
int j;
for(j=0; j<i; j++) // stop at i
printf("%c", a[j]); // output is flushed when \n is printed
}
Also test with i<50 not i<=50 because a[50] is outside the array bounds (I've generalized to sizeof(a))
Here is another way you can do this.
#include <stdio.h>
// define Start
#define ARRAY_SIZE 50
// define End
// Function Prototypes Start
void array_reader(char array[]);
void array_printer(char array[]);
// Function Prototypes End
int main(void) {
char user_input[ARRAY_SIZE];
printf("Please enter some characters (50 max)!\n");
array_reader(user_input);
printf("Here is what you said:\n");
array_printer(user_input);
return 0;
}
// Scans in characters into an array. Stops scanning if
// 50 characters have been scanned in or if it reads a
// new line.
void array_reader(char array[]) {
scanf("%c", &array[0]);
int i = 0;
while (
(array[i] != '\n') &&
(i < ARRAY_SIZE)
) {
i++;
scanf("%c", &array[i]);
}
array[i + 1] = '\0';
}
// Prints out an array of characters until it reaches
// the null terminator
void array_printer(char array[]) {
int i = 0;
while (array[i] != '\0') {
printf("%c", array[i]);
i++;
}
}
You may try with this code:
#include <stdio.h>
main()
{
char a[50];
int i;
printf("Give max 50 characters\n");
i=0;
do {
scanf("%c", &a[i]);
i=i+1;
} while(i<50 && a[i-1] != '\n');
a[i] = 0;
for(i=0; a[i] != 0; i++)
printf("%c", a[i]);
}
The function scanf("%c", pointer) will read one character at a time and place it at the pointer location. You are looking for '\0', which is a valid string terminator, but the newline character you get when you press ENTER and that you should be looking for is '\n'.
Also, it is a good idea to terminate the string you have read by adding a '\0' at the end (really a zero). Then use it to stop printing or you may print the "rest" of the contents of an uninitialized char array.
Can someone explain or correct me on the code i have?
I'm trying to input several characters and get the ascii value
ex: input: ab; output:9798
This is my code but there's a 10 at the end of it
#include <stdio.h>
int main() {
char c;
printf("Enter any character\n");
for (c=0; c<=122; c++)
{
scanf("%c", &c);
printf("%d",c);
}
return 0;
}
If you look at ASCII table, a decimal value of 10 is a newline character. In other words, you process \n character as part of the input. This can happen when user copy-pastes multiple lines, or when Enter key is pressed, for example. If you do not want that to happen, you need to take extra care to ignore \n. For example:
#include <stdio.h>
int main() {
char c;
printf("Enter any character\n");
for (c=0; c<=122; c++)
{
scanf("%c", &c);
if (c == '\n')
break; /* Or perhaps continue? Depends on what you actually want. */
printf("%d",c);
}
return 0;
}
Also, note that different systems may have different conventions as for what newline actually is. On UNIX, it is \n character only, on Windows, it might be a combination or \r and \n. So if you want to make your program portable, this needs to be taken into account. You can either do it yourself, or use some other library (GNU getline comes to mind). You can read more about newline here.
You may want to exclude some chars from the output and not only '\n', in that case you can try something like this:
#include <stdio.h>
int isEndingChar(char c) {
char terminators[3] = {'\r','\t','\n'}
int n;
for( n=0; n<3; n++ ) {
if( terminators[i]==c )
return 1;
}
return 0;
}
int main() {
char c;
printf("Enter any character\n");
for (c=0; c<=122; c++)
{
scanf("%c", &c);
if( isEndingChar( c ) )
break;
printf("%d",c);
}
return 0;
}