I was reading Kernighan Ritchie and there's this Character counting program, so I tried implementing
#include <stdio.h>
#include <stdlib.h>
int main()
{
char c;
int i;
c = getchar();
while (c != EOF)
i= i + 1;
printf("%d",i);
}`
When I compile and run this code, after I enter some characters there's no output after that. No number is printed and I can't figure out why. The code looks fine. I also tried using scanf() but the same thing happened.
The next example was for counting lines in input and the same problem was there too.
In your code, when you're hitting
i= i + 1;
the initial value of i is indeterminate. So, the whole program invokes undefined behavior. You need to initialize i.
To elaborate, i being an automatic local variable, unless initialized explicitly, the content is indeterminate. Using an indeterminate value in this case will lead to UB.
That said, a char is not able to hold a value of EOF, change the type to int.
After that, you're wrong in the logic. getchar() is not a loop on it's own, you need to keep calling getchar() inside the while loop body to update the value of c, used in the condition check in while.
int main()
Good. Not main() and not void main(). Keep it this way.
{
char c;
Bad. getchar() returns an int.
int i;
Bad. Not initialised, value is indeterminate. You are going to increment -7445219, or perhaps a kidney pie, who knows.
c = getchar();
Ok you have read a single character.
while (c != EOF)
But you cannot compare it to EOF because EOF doesn't fit in a char.
i= i + 1;
Looks like you forgot to do something in the body of the loop. Something that is going to change c perhaps so that your loop has a chance to finish.
printf("%d",i);
It is recommended to add a newline to the last line of your output.
}
That's all folks.
You only need to add an inicialization for "i"
int i = 0;
You missed the initialization:
int i = 0;
Related
Recently I saw this while loop condition in C in the example below but I have no idea what the while condition really means and how the compiler knows when it is done. Could someone explain it to me?
This is what I believe it means: while loop iterates through the char array until the ending of the array since there is nothing else then the while loop ends, or am I wrong? I tried to use the same while loop but in another language such as Go, however, the compiler threw an error saying that I cannot use a non-bool.
// C program to demonstrate
// example of tolower() function.
#include <ctype.h>
#include <stdio.h>
int main()
{
int j = 0;
char str[] = "GEEKSFORGEEKS\n";
// Character to be converted to lowercase
char ch = 'G';
// convert ch to lowercase using toLower()
char ch;
while (str[j]) { // <- this part, how is this a condition?
ch = str[j];
// convert ch to lowercase using toLower()
putchar(tolower(ch));
j++;
}
return 0;
}
the while loop can be understood as "while this string has characters" and as known in C strings or an array of chars contain a '\0' => Null character, in the end, once the while loop achieves it, it will stop the iteration.
So yeap! you are right.
You can think of an array of chars as following:
So as you see in the picture an array of chars is already a pointer, and each of the characters has an address, as well that the address of a pointer is the address of the first element, so when you declared
char str[] = "GEEKSFORGEEKS\n";
it was allocated in the memory like below:
[G][E][E][K][S][F][O][R][G][E][E][K][S][\n][\0]
The program will crash because you have a redeclaration of ch variable, as well there is no need to initialize the char ch = 'G'; since you're overriding it in the while loop and it will take str[j], and so you started iterating at j = 0 which the 1st index in the array [G], as you're incrementing the loop will go until the null character [\0] and stop because there's no iteration after the NULL, in other examples you might see the following condition in the loop: while(str[j] != '\0') which is similar to your condition but just more specific.
You can gain more performance by iterating through the pointer just like the following:
#include <ctype.h>
#include <stdio.h>
int main()
{
char *str = "GEEKSFORGEEKS\n";
while (*str)
putchar(tolower(*str++));
return 0;
}
Although, you got your answer. Still, I wanna add some more details or an explanatory answer here.
In C, a conditional statement will have either the value 1 or 0. In the end, they all are evaluated to Boolean values true or false or 1 or 0.
So first, try to understand or dry run that while(str[j]). Guess what will be the value of str[j] when j = 0. It'll be the first character "G". Similarly in the next iteration, you'll get the next character until NULL character or String Termination character. Now, anything in between those parentheses in while(str[j]) will be considered as a conditional statement and they all are evaluated to 1 or 0. Now here's the thing that anyhow if that conditional statement isn't being evaluated specifically to 0, then It'll be supposed to have the value of 1.
So, here str[j] when j = 0 will be evaluated as 1, then next character and so on. Now, when we find \0 which is an escape character equivalent to 0. So, at \0 while loop will terminate as the condition will be false.
Can, you tell me what will be the output of this program?
#include<stdio.h>
int main()
{
if(printf("Hello TraineeGuy\n"))
printf("TRUE");
else
printf("FALSE");
return 0;
}
An exercise asked to write a function that:
reads a sequence of alphabetic characters (without memorizing the sequence) that ends only when the users enters '\n'.
returns 1 if the number of capitalized letters went beyond the lower ones of at most an integer m, entered by the user, or 0 else.
I tried with the following code:
#include<stdio.h>
int read(int p,char c)
{
int M=0,m=0,d;
char A,Z,a,z;
while(c != '\n')
{
if(A<=c<=Z)
{
M++;
}
else if(a<=c<=z)
{
m++;
}
scanf("%c",&c);
}
if(M-m>0)
d=(m-M);
else
d=0;
if(d==0)
return 0;
else if (d<=p)
return 1;
}
int main()
{
int a,h;
char k;
scanf("%d", &h);
scanf("%c", &k);
a=read(h,k);
printf("%d\n",a);
return 0;
}
At this point, trying to execute the program with the gcc command, i noticed that the program was taking just the integer, let's say 2, and gave back 0 as if it entered in the function without taking the second scan on the character.
Besides the formal misconception and errors about the program and c function that i'm glad you rectify,
I was trying to understand, because as they say i'm trying to be self-taught, how scanf function and function work in general, when and to who priority is given.
For example in function read it's not clear to me when the value i'm returning to the function are taken putting a higher if as i did.
This isn't going to do what you probably expect
if(A<=c<=Z)
... for all sorts of reasons. Firstly, the values of A and Z are uninitialized. Second, the logic is written to be read by a mathematician, not a C compiler.
You almost certainly wanted this:
if('A'<=c && c<='Z')
... and remove the four variables char A,Z,a,z;
Note that use of character constants such as 'A' and 'Z' assumes a runtime environment using ASCII character sets. If you're interested in a more portable solution, you can look up isupper() and islower()
I am working on an assignment for school and am having trouble getting the correct output. I am unsure if there is a problem with my loop or a problem with the method of saving values with pointers. When I run the code I end up with something like this:
Output: There are 369224989 underscores and 0 exclamation points in the sentence.
The assignment specifies to use the prototype and the getchar() function to read the input. I feel like since the first value is so high it is an issue with my loop but I have been working on this for two days and haven't seen anything wrong with it (though I could be staring through it at this point).
In addition I get these warnings when I try and compile the program:
characters.c:28: warning: value computed is not used
characters.c:31: warning: value computed is not used
This makes me think that maybe it isn't communicating properly with the main function.
#include<stdio.h>
//this function prototype was required for the assignment
void count(int* num_, int* num_exclamation);
// intended to count the number of _ and ! in a string using pointers
int main()
{
int num_, num_exclamation;
count(&num_, &num_exclamation);
return 0;
}
void count(int* p_num_, int* p_num_exclamation)
{
char ch;
*p_num_ = *p_num_exclamation = 0;
//attempts to scan a string get the first character
printf("Enter a sentence: ");
ch = getchar();
//attempts to loop while incrementing if it is a ! or _
while(ch != '\n')
{
if(ch == '_')
*++p_num_;
if(ch == '!')
*++p_num_exclamation;
ch = getchar();
}
//prints result
printf("Output: There are %d underscores and %d exclamation points
in the sentence.\n", *p_num_, *p_num_exclamation);
}
This is the second time I have really interacted with pointers with the first being the other half of this assignment which is working properly. I am not particularly comfortable with them yet nor aware of all of their nuances. Any advice to get me looking in the right place would be greatly appreciated.
You have Undefined behavior in your code. *++p_num_; increments the pointer first and then it dereferences it. The value of it is not used. And this way, the pointer points to some memory which are not the variables you supposed it to be. Then you dereference it - that location contains indeterminate value and you print it. Accessing some memory which you don't have permisssion to is - UB.
(*p_num_)++
is the one you wanted. This holds for the other variable also - namely p_num_exclamation. Also return value of getchar is int not char - you should use int to hold the value returned by getchar.
I have written a small script to detect the full value from the user input with the getchar() function in C. As getchar() only returns the first character i tried to loop through it... The code I have tried myself is:
#include <stdio.h>
int main()
{
char a = getchar();
int b = strlen(a);
for(i=0; i<b; i++) {
printf("%c", a[i]);
}
return 0;
}
But this code does not give me the full value of the user input.
You can do looping part this way
int c;
while((c = getchar()) != '\n' && c != EOF)
{
printf("%c", c);
}
getchar() returns int, not char. And it only returns one char per iteration. It returns, however EOF once input terminates.
You do not check for EOF (you actually cannot detect that instantly when getchar() to char).
a is a char, not an array, neither a string, you cannot apply strlen() to it.
strlen() returns size_t, which is unsigned.
Enable most warnings, your compiler wants to help you.
Sidenote: char can be signed or unsigned.
Read a C book! Your code is soo broken and you confused multiple basic concepts. - no offense!
For a starter, try this one:
#include <stdio.h>
int main(void)
{
int ch;
while ( 1 ) {
ch = getchar();
x: if ( ch == EOF ) // done if input terminated
break;
printf("%c", ch); // %c takes an int-argument!
}
return 0;
}
If you want to terminate on other strings, too, #include <string.h> and replace line x: by:
if ( ch == EOF || strchr("\n\r\33", ch) )
That will terminate if ch is one of the chars listed in the string literal (here: newline, return, ESCape). However, it will also match ther terminating '\0' (not sure if you can enter that anyway).
Storing that into an array is shown in good C books (at least you will learn how to do it yourself).
Point 1: In your code, a is not of array type. you cannot use array subscript operator on that.
Point 2: In your code, strlen(a); is wrong. strlen() calculates the length of a string, i.e, a null terminated char array. You need to pass a pointer to a string to strlen().
Point 3: getchar() does not loop for itself. You need to put getchar() inside a loop to keep on reading the input.
Point 4: getchar() retruns an int. You should change the variable type accordingly.
Point 5: The recommended signature of main() is int main(void).
Keeping the above points in mind,we can write a pesudo-code, which will look something like
#include <stdio.h>
#define MAX 10
int main(void) // nice signature. :-)
{
char arr[MAX] = {0}; //to store the input
int ret = 0;
for(int i=0; i<MAX; i++) //don't want to overrrun array
{
if ( (ret = getchar())!= EOF) //yes, getchar() returns int
{
arr[i] = ret;
printf("%c", arr[i]);
}
else
;//error handling
}
return 0;
}
See here LIVE DEMO
getchar() : get a char (one character) not a string like you want
use fgets() : get a string or gets()(Not recommended) or scanf() (Not recommended)
but first you need to allocate the size of the string : char S[50]
or use a malloc ( #include<stdlib.h> ) :
char *S;
S=(char*)malloc(50);
It looks like you want to read a line (your question mentions a "full value" but you don't explain what that means).
You might simply use fgets for that purpose, with the limitation that you have to provide a fixed size line buffer (and handle - or ignore - the case when a line is larger than the buffer). So you would code
char linebuf[80];
memset (linebuf, 0, sizeof(linbuf)); // clear the buffer
char* lp = fgets(linebuf, sizeof(linebuf), stdin);
if (!lp) {
// handle end-of-file or error
}
else if (!strchr(lp, '\n')) {
/// too short linebuf
}
If you are on a POSIX system (e.g. Linux or MacOSX), you could use getline (which dynamically allocates a buffer). If you want some line edition facility on Linux, consider also readline(3)
Avoid as a plague the obsolete gets
Once you have read a line into some buffer, you can parse it (e.g. using manual parsing, or sscanf -notice the useful %n conversion specification, and test the result count of sscanf-, or strtol(3) -notice that it can give you the ending pointer- etc...).
I'm attempting to use the getc() function to copy the contents of one file into another. But I'm making an unknown logical error because the output of the following program is a bunch of garbage.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
FILE *f;
FILE *write;
f = fopen("nums.csv","r");
write = fopen("numsWrite.dat","w");
char tempChar;
int i;
for(i = 0; (tempChar = getc(f)) != EOF; i++)
{
tempChar = getc(f);
fprintf(write,"%c",tempChar);
}
fprintf(write,"\n");
fclose(f);
fclose(write);
return 0;
}
content of nums.csv is:
1256,2548,35151,15,56,38
program returns:
2624,55,55,8
There are several problems with your code.
int main() should be int main(void); this is a minor issue that almost certainly won't hurt anything, but the latter is more correct.
You don't check whether the fopen() calls succeed.
You're using i to count the characters you read, but you never do anything with its value.
The getc() function returns a result of type int, so you should definitely make tempChar an int. The reason for this is that it can return either a valid character value (which will fit in a char object) or the value EOF which is typically -1. By storing the result of getc() in a char object, either you'll never see EOF (if plain char is unsigned), or you won't be able to distinguish EOF from a valid input character.
In a comment on Razvan's answer, you said you changed the test to tempChar != EOF. Apart from the problem I explained above, on the first iteration of the loop tempChar has not been initialized, and the result of the comparison is unpredictable.
The conventional way to write an input loop using getc() is:
int c;
while ((c = getc(f)) != EOF) {
/* do something with c */
}
As a matter of style, write is not a very good name for a FILE*. For one thing, there's a function of that name (defined by POSIX, not by C, but it's still potentially confusing). You might call the FILE* objects in and out instead.
You call getc two times: once in the for condition and once in the for body. Delete this line: tempChar = getc(f); and try again.