This question already has answers here:
If statements not working?
(2 answers)
Closed 7 years ago.
I'm trying to ask a user to enter a string of characters. I want my program to continue scanning in the characters one at a time until it sees the \n character (i.e., when the user presses the ENTER key).
It appears that the code I've written doesn't store the characters to the array for some reason. I know this because the for loop containing the printf() statement doesn't reproduce the characters that are entered into the terminal. My last ditch effort was to print out a[0] in case something was going wrong with my loop, but it still showed that nothing was stored to my character array.
Any explanations? (Please don't suggest that I use the string.h library--I do not wish to use it for my purposes.)
#include <stdio.h>
int main(void)
{
char a[21];
int i;
printf("enter a bunch of characters: ");
for (i = 0; ; i++)
{
scanf("%c", &a[i]);
if (a[i] = '\n')
{
break;
}
}
printf("the size of char array is %d\n", sizeof(a)/sizeof(a[0]));
for (i = 0; a[i] != '\0'; i++)
{
printf("%c", a[i]);
}
printf("%c", a[0]);
return 0;
}
if (a[i] == '\n') { break; }
Modify if statement as above and check.
Related
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.
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 5 years ago.
Improve this question
I have the following problem reading two strings through scanf: I insert the first string and everything it's OK, but after I insert the second one the first one changes.
#include<stdio.h>
#define N 6
#define K 2
int main(){
char a[N];
char b[K];
int i = 0,j=0;
printf("first word\n\n\n");
scanf("%s", a);
for(i = 0; i <= N; i++){
printf("%c", a[i]);
}
printf("second word \n\n\n");
scanf("%s", b);
for(i = 0; i <= N; i++){
printf("%c", a[i]);
}
}
The first time it prints it correctly. The second time it prints a similar string (maybe the first scanf is still getting the input when I'm inserting the second one)
To begin, you are printing the array a twice; it seems that you mean to print b with the second loop. But there is a problem in your loops. They are going out of array bounds. Since arrays are zero-indexed in C, you need:
for (i = 0; i < N; i++) {}
for a, and:
for (i = 0;i < K; i++) {}
for b.
But even this is not quite right, since the input strings may not entirely fill the arrays. You really need to terminate the loop when the null-terminator is reached, or when the end of the array has been reached:
for (i = 0; a[i] != '\0' && i < N; i++) {}
and:
for (i = 0; b[i] != '\0' && i < K; i++) {}
Of course, it would be simpler to just use puts() to print the strings.
It seems that the inputs (abcabc and abc) were too large for the arrays, causing buffer overflow. This can be avoided by specifying maximum widths when using the %s conversion specifier with scanf().
Here is a modified version of the posted code. I increased the sizes of N and K by one, since it appears that space for null-terminators was not considered in the original code:
#include <stdio.h>
#define N 7
#define K 3
int main(void)
{
char a[N];
char b[K];
int i = 0;
printf("first word\n\n\n");
scanf("%6s", a);
for (i = 0; a[i] != '\0' && i < N; i++) {
printf("%c", a[i]);
}
putchar('\n');
printf("second word \n\n\n");
scanf("%2s", b);
for (i = 0; b[i] != '\0' && i < K; i++) {
printf("%c", b[i]);
}
putchar('\n');
return 0;
}
You are printing a twice, change the second printf("%c", a[i]); to printf("%c", b[i]); .
The problem you are experiencing is because you invoke undefined behavior by failing to insure the strings are nul-terminated and by using incorrect limits regarding b. For instance, you
#define N 6
#define K 2
...
char a[N], b[K];
a can hold a total of 5-chars + the nul-terminator, for a total of 6-chars. b on the other hand, can only hold 1-char + the nul-terminator for a total of 2-chars.
When you then subsequently loop of both a and b with for(i = 0; i <= N; i++), not only have you guaranteed to access an element outside the bounds of the array, e.g. a[6] (valid indexes are 0-5), you have also invoked undefined behavior for any a with less that 6 total characters by attempting to read from an uninitialized value (those uninitialized array elements after the last valid char in word of say, 3-chars) When you invoke Undefined Behavior, the execution of your code is unreliable from that moment forward.
In your case you can eliminate undefined behavior by using field width modifiers to limit the number of characters placed in the arrays by scanf itself, e.g.
if (scanf ("%5s", a) != 1) {
fprintf (stderr, "error: invalid input - a.\n");
return 1;
}
You validate the return of scanf to insure the proper number of conversions have taken place, or you handle the error if they have not.
You prevent reading beyond the bounds of the array by limiting your read and output char loop to only valid characters within the array. You do that by checking the character to be printed is not the nul-terminating character, and when the nul-terminating character is reached, you exit the loop without attempting to print it.
Putting those pieces together, you could do something similar to the following (note j is unused in your code so it is commented out):
#include <stdio.h>
#define N 6
#define K 2
int main (void ) {
char a[N], b[K];
int i = 0/*, j = 0*/;
printf ("enter first word: ");
if (scanf ("%5s", a) != 1) {
fprintf (stderr, "error: invalid input - a.\n");
return 1;
}
for (i = 0; a[i] && i < N; i++)
printf ("%c", a[i]);
putchar ('\n');
printf ("enter second word: ");
if (scanf ("%1s", b) != 1) {
fprintf (stderr, "error: invalid input - b.\n");
return 1;
}
for (i = 0; b[i] && i < N; i++)
printf ("%c", b[i]);
putchar ('\n');
return 0;
}
Example Use/Output
$ ./bin/twowords
enter first word: cats
cats
enter second word: dogs
d
I would strongly caution you to consider reading line-oriented input with a line-oriented input function like fgets. This eliminates many pitfalls for new programmers. The only additional step when using fgets is to recall it reads up-to-and-including the trailing '\n', so you need to trim the '\n' from the string read.
Look things over an let me know if you have further questions.
For the second printf you have to write
printf("%c", b[i]);
As per inputs(abcabc and abc ) you mentioned your are providing to scanf are causing overflow for both the variables a and b,
You should enter string of length 5 for first and 1 for second keeping space for \0 for both the strings
Edit: Also change loop condition from i <= N to i<N or i<sizeof(a).
Please note the loop will print garbage characters past string length if the length of string happens to be less than 5
I see two things that you can do here:
Use another big buffer array that you will load data to, and that copy data to specyfic array. Than you will get max 6 letters of first word in a[], and max 2 letters of second word in b[]. But you will be able to load 2 words.
Scanf specyfic amount of chars like #xing mentiond in comment.
scanf("%6s",word) //general use, not in OP's case
Than when you've got longer word than size that you set up, you will have the rest of input as input in second word.
This question already has answers here:
scanf issue when reading double
(2 answers)
Closed 5 years ago.
sorry for the remedial question. Been troubleshooting to try and find the error and I have come up empty.
I need to write a program that alphabetizes a list of inputs. The first input is the integer value of the number of inputs. Each input ends with a new line character.
int main()
{
int word_total;
char word_in[100][30], t[30];
int i, j;
printf("\nPlease the number of words you wish to sort: \n");
scanf("%d", &word_total);
printf("\nPlease enter a single word at a time. After each word, press return.\n");
for (i = 0; i < (word_total); i++)
{
scanf("%s\n", word_in[i]);
}
for (i = 1; i < (word_total); i++)
{
for (j = 1; j < (word_total); j++)
{
if (strcmp(word_in[j - 1], word_in[j]) > 0)
{
strcpy(t, word_in[j - 1]);
strcpy(word_in[j - 1], word_in[j]);
strcpy(word_in[j], t);
}
}
}
printf("\nSorted list:\n");
for (i = 0; i < (word_total); i++)
{
printf("%s\n", word_in[i]);
}
printf("\n");
}
The problem: the input of words takes word_total + 1. For instance, if word_total = 5, I have to input 6 words. The last word that is input is ignored and not included in the "Sorted list". I can fix the problem by:
for (i = 0; i < (word_total - 1); i++)
{
scanf("%s\n", word_in[i]);
}
but then the "Sorted list" is short one word. I've tried changing "<" to "<=", etc, but haven't found a fix.
Thank you for your help!
The problem seems to be
scanf("%s\n", word_in[i]);
which, due to the "\n", will attempt to read more whitespace following the string (until it finds another non-whitespace; note that any whitespace character actually means any number of whitespace characters; the \n does not match just a single newline as you apparently expect). You should remove the "\n" from the scanf format and eat the newline with a getchar() or similar.
PS: not testing the return value from scanf() is asking for trouble.
I am writing a program for comparing two strings without using strcmp(). But, am unable to get my desired result.
Here is the code for my program.
#include<stdio.h>
int main(int argc, char const *argv[]) {
int i,j;
char a[90],b[90];
printf("Enter the first string:");
scanf("%s", &a[90]);
printf("Enter the second string:");
scanf("%s", &b[90]);
for ( i = 0; a[i] != '\0' && b[i] != '\0'; i++) {
if (a[i] == b[i]) {
/* code */
printf("Equal %d \n", a[i]-b[i]);
continue;
} if (a[i] > b[i]) {
/* code */
printf("ai is big %d \n", a[i]-b[i]);
break;
}
if (a[i] < b[i]) {
/* code */
printf("%d bi is the biggest \n", a[i]-b[i]);
break;
}
}
return 0;
}
When I execute the program in my terminal the compiler takes the input strings and then stops. I tried it a lot but am unable to figure it out. Can anyone help me out...!
The name of your first array is a, not a[90].
Similarly, the name of your second array is b, not b[90].
The expressions a[90] and b[90] name one element after the end of a and b.
So, by writing &a[90] and &b[90] you are instructing scanf to write just after each array, which is very bad and wrong.
You probably meant &a[0] and &b[0]?
However, scanf is very dangerous and you should not be using it at all.
The expressions '&a[90]' and '&b[90]' each generate the addresses of the last entries in arrays a and b. That means you are reading the strings into unallocated stack memory, not into the arrays. You need to just use plain 'a' and 'b' in the scanf() calls.
If you are now wondering "How does scanf know to limit the strings to 90 characters?", the answer is IT NEVER DOES. Scanf assumes the caller has provided enough buffer space for the entered string (including terminating null-char). If you really need to be able to enter arbitrarily long strings, you will have to perform much more sophisticated buffer management. If you only want to ensure less than 90 characters are ever entered, you need to drop down to getting one character at a time (and I believe you will have to explicitly check for the terminating newline) and count them to ensure you don't overflow the buffer.
There is some issue with the given code in question.
issues
1- Unused variable j.
2- While getting the string from user, in scanf a[90] and b[90] is used that means string will be stored from 90th array index. This can lead to some memory issues and output will have some garbage values.
Its is good to use a[0] and b[0] in scanf. We can use array name in scanf as array name points to the starting address of array.
scanf ("%s", a);
scanf ("%s", b);
Correct code :
#include "stdio.h"
int main(int argc, char const *argv[])
{
int i;
char a[90],b[90];
printf("Enter the first string:");
scanf("%s", a);
printf("Enter the second string:");
scanf("%s", b);
for ( i = 0; a[i] != '\0' || b[i] != '\0'; i++) {
if (a[i] == b[i]) {
/* code */
printf("Equal %d \n", a[i]-b[i]);
continue;
} if (a[i] > b[i]) {
/* code */
printf("a is big %d \n", a[i]-b[i]);
break;
}
if (a[i] < b[i]) {
/* code */
printf("%d b is the biggest \n", a[i]-b[i]);
break;
}
}
return 0;
}
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 7 years ago.
Improve this question
1.actually I want to first give a number N (no. of strings I want to enter) as an input then in next line a string using gets().But when I press enter then the no. of strings I could enter is N-1.I tried using printf("\n") but it didn't work.Please anyone could help me in this.eg:
//code
int N,i,arr[N];
char str[50];
scanf("%d",&N) //no. of strings required
for(i=0;i<N;i++)
{
gets(str);
arr[i]=strlen(a);
}
for(i=0;i<N;i++)
{
printf("%d\n",arr[i]);
}
i want to enter my input to be like this:
2 //no. of strings
ABCFD //string 1
ASWD //string 2
//But actually what i am getting using printf("\n")
and output:
5
4
but what i am getting:
2
//blank space
ASWD //string 2
and output
0
4
After entering a value for N there remains a newline in the input buffer, which is accepted by the following gets as a blank input. In any case gets is a deprecated function: please use fgets such as like this. I've printed each entry to show there is a newline at the end of each, and removed that newline.
#include <stdio.h>
#include <string.h>
int main(void) {
int N, i;
char str[50];
printf("Enter number of cases\n");
scanf("%d%*c", &N); // read newline too, but discard
for(i=0; i<N; i++)
{
printf("\nEnter string\n");
if (fgets(str, sizeof str, stdin) == NULL)
return 1;
printf("Shows newline >>%s<<\n", str); // show that newline is retained
str [ strcspn(str, "\r\n") ] = 0; // remove trailing newline
printf("After removal >>%s<<\n", str); // show that newline was removed
}
return 0;
}
Program output
Enter number of cases
2
Enter string
one
Shows newline >>one
<<
After removal >>one<<
Enter string
two
Shows newline >>two
<<
After removal >>two<<
Try it --
int lineNumbers;
scanf("%d", &lineNumbers);
char **linesOfString = (char**) malloc(lineNumbers * sizeof(char *));
int i;
for(i = 0; i < lineNumbers; i++) {
fflush(stdin);
linesOfString[i] = (char *) malloc(255 * sizeof(char));
scanf("%s", linesOfString[i]);
}
for(i = 0; i < lineNumbers; i++) {
printf("%s", linesOfString[i]);
}
free(linesOfString);
return 0;
It sounds like you are not getting the number of strings expected, is this correct?
If this is the case, look at your looping code.
The most likely newbie mistake is with indexing. Arrays in C are 0 indexed.
This means that if you have int test[3], the indexes of test will be 0, 1, and 2. This means that the highest index WILL be N-1.
So, make sure that the first string you are accepting is being placed into index 0, and not index 1.