C beginner question: Array is not printing - c

I'm trying to produce a simple program which will read a string and print it along with the number of characters in it.
The character count seems fine, but it won't print the full string. For whatever reason, it will print only the second character. I have been reviewing my code and I still cannot figure out why this is happening.
If I input: abcdef
It will print out: 1
b 2
3
4
5
6
Instead of the intended: a 1 b 2 c 3 d 4 e 5 f 6
#include <stdio.h>
int main()
{
char c;
char str[0] = {};
int i;
int charcount;
charcount = 0;
for (i = 0; (c = getchar()) != '#' && c != '\n'; i++) {
c = str[i];
charcount++;
printf("%c %d \n", str[i], charcount);
//if(charcount > 80)
// printf("%d", z[i]);
}
return 0;
}
Any help is appreciated. Thanks.

You have a variable str that is of zero length, and you try to access various elements in it (but it has none, so this is undefined behavior)
Just get rid of it and use c directly:
#include <stdio.h>
int main()
{
char c;
int i;
int charcount;
charcount = 0;
for (i = 0; (c = getchar()) != '#' && c != '\n'; i++) {
charcount++;
printf("%c %d \n", c, charcount);
}
return 0;
}

For starters according to the C Standard the function main without parameters shall be declared like
int main( void )
This declaration
char str[0] = {};
is invalid with two respects. The array size shall be greater than zero. And the the braces that initialize the array shall not be empty.
In fact the array is redundant because what you are trying to do is just output entered characters.
This assignment
c = str[i];
does not make sense even if the array was be declared correctly because the entered character is overwritten by the (non-existent) element of the array.
The variable c itself should have the type int.
If you just need to perform this
I'm trying to produce a simple program which will read a string and
print it along with the number of characters in it.
then the program can look for example the following way
#include <stdio.h>
int main(void)
{
size_t i = 0;
for ( int c = getchar(); c != EOF && c != '\n' && c != '#'; c = getchar() )
{
++i;
printf( "%c %zu ", c, i );
}
putchar( '\n' );
return 0;
}
If to enter
abcdef
then the output will be
a 1 b 2 c 3 d 4 e 5 f 6
If you want to use a character array and store entered characters in the array then the program can look like
#include <stdio.h>
int main(void)
{
enum { N = 100 };
char s[N];
int c;
for ( size_t i = 0; i < N && ( c = getchar( ) ) != EOF && c != '\n' && c != '#'; i++ )
{
s[i] = c;
printf( "%c %zu ", s[i], i + 1 );
}
putchar( '\n' );
return 0;
}
The program output will be the same as above if to enter for example abcdef.

I took your question to mean you were looking to store the characters that are entered into an array and print them out as you go. You want to give the array an initial size (I chose 99) and then add characters to the array as you go. You can keep track of the length so you know where the "end" is. There are better ways to manage string data in C, but here you go.
#include <stdio.h>
int main()
{
char c;
char str[99] = {};
int i;
int charcount;
charcount = 0;
for (i = 0; (c = getchar()) != '#' && c != '\n'; i++) {
// c = str[i];
str[i] = c;
charcount++;
printf("%c %d \n", str[i], charcount);
//if(charcount > 80)
// printf("%d", z[i]);
}
return 0;
}
Some additional thoughts:
You probably want to look at something like string.h
If you are going to keep the char array, you need to protect against going over the size of the array
Adding a little blurb about what you expect your program to do, what the requirements are, example input, output, etc would have helped get better answers from the community

Related

Trying to break out of fgets while loop

#include <stdio.h>
#include <string.h>
int main(){
char c[20], result[50];
int bool = 0, count = 0, i;
while(fgets(c,20,stdin) != NULL){
int stringSize = strlen(c);
if(stringSize == 11){
int ascii = (int)(c[i]);
for(i = 0; i < stringSize; i++){
if(ascii >= 'A' && ascii <= 'Z'){
bool = 1;
}
}
}
}
if(bool == 1){
count++;
strcat(result,c);
}
printf("%d", count);
printf("%s",result);
}
Good morning, I am fairly new to programming, and I've spent quite a while Googling and searching around for this issue already, but I can't seem to wrap my head about it.
Basically I'm trying to filter an fgets so that it reads each string, and if they're capital letters, they're "valid". However, I can't even get the fgets to stop accepting more input.
Edit: The idea is to store in result every String that has 10 capital letters, and for the fgets while loop to break once the user gives no input ('\0')
If you are entering strings from the standard input stream then it is better to rewrite the condition of the while loop the following way
while( fgets(c,20,stdin) != NULL && c[0] != '\n' ){
In this case if the user just pressed the Enter key without entering a string then the loop stops its iterations.
Pay attention to that fgets can append the new line character '\n' to the entered string. You should remove it like
c[ strcspn( c, "\n" ) ] = '\0';
Then you could write
size_t n = strlen( c );
if ( n == 10 )
{
size_t i = 0;
while ( i != n && 'A' <= c[i] && c[i] <= 'Z' ) ++i;
bool = i == 10;
}
Pay attention to that it is a bad idea to use the name bool because such a name is introduced as a macro in the header <stdbool.h>.
Also it seems this if statement
if(bool == 1){
count++;
strcat(result,c);
}
must be within the while loop. And the array result must be initially initialized
char c[20], result[50] = { '\0' };

Copying the input from `getchar()` to another variable

In the following code example from K&R's book, if I replace putchar(c) with printf("%c", c) the code works the same. But if I replace it with printf("%d", c) it gives gibberish output.
#include <stdio.h>
int main() {
int c;
c = getchar();
while (c != EOF) {
putchar(c);
c = getchar();
}
}
From here, I learned that the getchar() converts the stdin to an 8-bit character whose value ranges from 0 to 255.
Now I want to print the value of c using putchar(c) in one line and printf("%d", c) in another line. So I wrote the following code:
#include <stdio.h>
int main() {
int c, b;
c = getchar();
b = c;
while (c != EOF && c != 10) {
printf("%c",c);
c = getchar();
}
printf("\n");
while (b != EOF && b != 10) {
printf("%d\t",b);
b = getchar();
}
}
I used the condition c != 10 as the newline character is read as 10 by getchar(). I expected the code to work as
$ ./a.out
783
783
55 56 51
but the program terminates as
$ ./a.out
783
783
55
I understand that getchar() takes input from stdin and the variable b is not stdin. So how should I copy the variable c to b so that my program works as I expect it to?
The problem is that your code does not (and cannot, as it stands) 'remember' the inputs you gave in the first loop. So, after you have finished that loop, your second loop is wanting to read in the characters for b (after it has output the first value, which is remembered from the earlier b = c line).
So, after outputting 55 (the integer value of the character 7), it is waiting for further input.
Probably the easiest way to get the output that you're looking for is to have an array of input characters. Then, you can output the %c values as you read them (as before), then re-run the outputs using the %d format in a subsequent for loop.
Here is a demonstration that does what I think you're after:
#include <stdio.h>
#define MAXINS 20 // Set to the maximum number of input characters you want to allow
int main()
{
int c[MAXINS];
int i = 0, n = 0;
c[0] = getchar();
while (i < MAXINS && c[i] != EOF && c[i] != 10) {
printf("%c", c[i]);
c[++i] = getchar();
++n;
}
printf("\n");
for (i = 0; i < n; ++i) {
printf("%d\t", (int)(c[i]));
}
return 0;
}
Feel free to ask for further clarification and/or explanation.
EDIT: On the point in the your first paragraph, "But if I replace it with printf("%d", c) it gives gibberish output." Well, when I try the following code and give 783 and then hit return (which generates a newline) I get the expected 55565110 as the output:
int main()
{
int c;
c = getchar();
while (c != EOF) {
printf("%d", c);
c = getchar();
}
return 0;
}
This may look like gibberish, but it's just the same output as you 'expect' in your later code, but without the spaces and with the addition of the 10 for the newline.
You need to have every character stored, because once you read a char from stdin, it is not present in stdin anymore.
Since you want the newline character in the end as a part of the input, you should use fgets to take the input.
Say you are taking an input that could have a maximum of 100 characters.
#include <stdio.h>
int main(void) {
char c[100]; // A char array
fgets(c,100,stdin);
int x=0;
while (c[x] != 10 && c[x] != EOF)
printf("%c",c[x++]);
printf("\n");
x = 0;
while (c[x] != 10 && c[x] != EOF) // You can simply compare it with the newline character too.
printf("%d ",c[x++]);
printf("\n");
return 0;
}
There are many ways to do this. You can also read stdin character-by-character ans store it in an array. However, since you need to display the ASCII values of the characters in another line after displaying the characters themselves, you will have to store them in an array.
You are copying only the first input, to copy the whole string you need to store each input in a buffer and check if the string doesn't overflow that buffer on each iteration:
int main(void)
{
enum {size = 256};
char buffer[size];
size_t count = 0;
int c;
while ((c = getchar()) && (c != '\n') && (c != EOF))
{
printf("%c", c);
if (count < size)
{
buffer[count++] = (char)c;
}
}
printf("\n");
for (size_t iter = 0; iter < count; iter++)
{
printf("%d\t", buffer[iter]);
}
printf("\n");
}
If you don't want to limit the buffer to an arbitrary size then you need to change your approach to use dynamic memory (realloc or a linked list)

C programming, segmentation fault core dump

I am trying to make a program which takes in a input of "Hello" and outputs "olleH" from reversing the order of the characters. However I keep getting a segmentation fault and I don't understand why
#include <stdio.h>
#include<string.h>
int main()
{
int i;
int size;
char s[100],a[100];
printf("Enter the word you want to get reversed: ");
scanf("%s",s);
while(s[i]!='\0')
{
a[i]=s[i];
i++;
}
size=sizeof(s);
while(i<sizeof(s))
{
s[i]=a[size];
}
printf("The reversed string is : %s",s);
}
Another simple way to reverse string.
Try this:
while(s[++i]!='\0'); // find the size of string
while(i>=0)
a[j++] = s[--i]; // reverse the string
a[j]='\0';
printf("The reversed string is : %s",a);
This while loop
while(i<sizeof(s))
{
s[i]=a[size];
}
does not make sense because index i has a value that points to outside the entered string (provided that it was initially correctly initialized) and the loop is infinite because i is not changed (and was not initially initialized) in the loop and also the right hand expression of this statement
s[i]=a[size];
is always the same and again refers memory outside the array.
Take into account that neither function declared in <string.h> is used in the program. So the header may be removed.
The program can look the following way
#include <stdio.h>
#define N 100
int main()
{
char s[N], d[N];
printf( "Enter the word you want to get reversed: " );
fgets( s, N, stdin );
size_t n = 0;
while ( s[n] != '\0' && s[n] != '\n' ) n++;
for ( size_t i = 0; i != n; i++ ) d[i] = s[n-i-1];
d[n] = '\0';
printf( "The reversed string is : %s\n", d );
return 0;
}
You can reverse a string without using an auxiliary array. For example
#include <stdio.h>
#define N 100
int main()
{
char s[N];
printf( "Enter the word you want to get reversed: " );
fgets( s, N, stdin );
size_t n = 0;
while ( s[n] != '\0' && s[n] != '\n' ) n++;
s[n] = '\0';
for ( size_t i = 0; i < n / 2; i++ )
{
char c = s[i];
s[i] = s[n-i-1];
s[n-i-1] = c;
}
printf( "The reversed string is : %s\n", s );
return 0;
}
The problem is in this part:
size=sizeof(s);
while(i<sizeof(s))
{
s[i]=a[size];
}
sizeof(s) will be 100 whereas the string you read from input can be less than that -- which would be undefined if you access uninitialized parts of s. So, you want to use strlen() to get the actual size of the string and use it to reverse.
Notice that scanf() is unsafe as it's written (what if you input more than 100 chars?). Suggest using fgets() instead.

Can you help me with multiple errors in C?

I'm pretty new to C and I'm having difficulty with a few different concepts, including pointers, arrays, and reading files. Here is my program I've started, I'm sure their are a few errors, could you show me what I'm doing wrong? The program is supposed to read the letters from congress.txt and store them as capital letters without spaces, I also tried to make a little test which will print the letters for me so I can see if the characters in the array store are correct. I've heard that I shouldn't test against != EOF here before but my teacher has used that and I don't want to simply copy something I don't understand.
This is what is in congress.txt:
Congress shall make no law respecting an establishment of religion, or prohibiting the free exercise thereof; or abridging the freedom of speech, or of the press; or the right of the people peaceably to assemble, and to petition the government for a redress of grievances.
#include<stdio.h>
int processFile(int *store);
int cipher(int *store, int *code);
int main(void){
int store[300], code[300], i;
processFile(store);
for (i = 0; store[i] != 0; ++i){ //does a print test of store so I can see if the txt was stored properly
printf("%c", store[i]);
}
getchar();
return;
}
int processFile(int *store){
int i, a = 0;
FILE *f = fopen("congress.txt", "r");
for (i = 0; a != EOF;){
fscanf(f, "%c", &a); //store character in a
if (a <= 'Z' && a >= 'A'){ //store capital letters
store[i] = a;
i++;
}
if (a <= 'z' && a >= 'a'){ //store lower case letters as capital
store[i] = a - 32;
i++;
}
}
}
This line:
fscanf(f, "%c", a);
should be:
fscanf(f, "%c", &a);
This loop doesn't make any sense.
for (i = 0; b != NULL; i++)
printf("%s", store[i]);
b = store[i + 1];
}
store[i] is an int, so you can't print it with "%s". I think you meant printf("%c", store[i]); which means to print the characters whose character code is that int (which is OK, because you read this earlier with scanf).
b != NULL should be b != 0, but this tests an uninitialized value of b on the first time around the loop. Try this instead:
for ( i = 0; store[i] != 0; ++i )
printf("%c", store[i]);
In the other piece of code, 65, 90, 97, 122 are more clearly expressed as 'A', 'Z', 'a', 'z' respectively.
You may want to consider using the isupper, islower functions from <ctype.h>. a - 32 should be replaced by toupper(a);.
I would change your body of processFile to:
int i, a = 0;
FILE *f = fopen("congress.txt", "r");
if(f)
{
for( i=0; i<300 && ((a=fgetc(f)) != EOF); i++)
{
if ( isupper(a) ){ //store capital letters
store[i] = a;
}
else if ( islower(a) ){ //store lower case letters as capital
store[i] = toupper(a);
}
}
fclose(f);
}
if (i==300) i--;
store[i] = 0; // always put a zero after the last element
// since your loop in main depends on it to exit.
This takes care of EOF problems, and also fixes potential overflows of the store array. (You might want to pass store's max size to the routine instead of hardcoding 300...)

C program, Reversing an array

I am writing C program that reads input from the standard input a line of characters.Then output the line of characters in reverse order.
it doesn't print reversed array, instead it prints the regular array.
Can anyone help me?
What am I doing wrong?
main()
{
int count;
int MAX_SIZE = 20;
char c;
char arr[MAX_SIZE];
char revArr[MAX_SIZE];
while(c != EOF)
{
count = 0;
c = getchar();
arr[count++] = c;
getReverse(revArr, arr);
printf("%s", revArr);
if (c == '\n')
{
printf("\n");
count = 0;
}
}
}
void getReverse(char dest[], char src[])
{
int i, j, n = sizeof(src);
for (i = n - 1, j = 0; i >= 0; i--)
{
j = 0;
dest[j] = src[i];
j++;
}
}
You have quite a few problems in there. The first is that there is no prototype in scope for getReverse() when you use it in main(). You should either provide a prototype or just move getReverse() to above main() so that main() knows about it.
The second is the fact that you're trying to reverse the string after every character being entered, and that your input method is not quite right (it checks an indeterminate c before ever getting a character). It would be better as something like this:
count = 0;
c = getchar();
while (c != EOF) {
arr[count++] = c;
c = getchar();
}
arr[count] = '\0';
That will get you a proper C string albeit one with a newline on the end, and even possibly a multi-line string, which doesn't match your specs ("reads input from the standard input a line of characters"). If you want a newline or file-end to terminate input, you can use this instead:
count = 0;
c = getchar();
while ((c != '\n') && (c != EOF)) {
arr[count++] = c;
c = getchar();
}
arr[count] = '\0';
And, on top of that, c should actually be an int, not a char, because it has to be able to store every possible character plus the EOF marker.
Your getReverse() function also has problems, mainly due to the fact it's not putting an end-string marker at the end of the array but also because it uses the wrong size (sizeof rather than strlen) and because it appears to re-initialise j every time through the loop. In any case, it can be greatly simplified:
void getReverse (char *dest, char *src) {
int i = strlen(src) - 1, j = 0;
while (i >= 0) {
dest[j] = src[i];
j++;
i--;
}
dest[j] = '\0';
}
or, once you're a proficient coder:
void getReverse (char *dest, char *src) {
int i = strlen(src) - 1, j = 0;
while (i >= 0)
dest[j++] = src[i--];
dest[j] = '\0';
}
If you need a main program which gives you reversed characters for each line, you can do that with something like this:
int main (void) {
int count;
int MAX_SIZE = 20;
int c;
char arr[MAX_SIZE];
char revArr[MAX_SIZE];
c = getchar();
count = 0;
while(c != EOF) {
if (c != '\n') {
arr[count++] = c;
c = getchar();
continue;
}
arr[count] = '\0';
getReverse(revArr, arr);
printf("'%s' => '%s'\n", arr, revArr);
count = 0;
c = getchar();
}
return 0;
}
which, on a sample run, shows:
pax> ./testprog
hello
'hello' => 'olleh'
goodbye
'goodbye' => 'eybdoog'
a man a plan a canal panama
'a man a plan a canal panama' => 'amanap lanac a nalp a nam a'
Your 'count' variable goes to 0 every time the while loop runs.
Count is initialised to 0 everytime the loop is entered
you are sending the array with each character for reversal which is not a very bright thing to do but won't create problems. Rather, first store all the characters in the array and send it once to the getreverse function after the array is complete.
sizeof(src) will not give the number of characters. How about you send i after the loop was terminated in main as a parameter too. Ofcourse there are many ways and various function but since it seems like you are in the initial stages, you can try up strlen and other such functions.
you have initialised j to 0 in the for loop but again, specifying it INSIDE the loop will initialise the value everytime its run from the top hence j ends up not incrmenting. So remore the j=0 and i=0 from INSIDE the loop since you only need to get it initialised once.
check this out
#include <stdio.h>
#include <ctype.h>
void getReverse(char dest[], char src[], int count);
int main()
{
// *always* initialize variables
int count = 0;
const int MaxLen = 20; // max length string, leave upper case names for MACROS
const int MaxSize = MaxLen + 1; // add one for ending \0
int c = '\0';
char arr[MaxSize] = {0};
char revArr[MaxSize] = {0};
// first collect characters to be reversed
// note that input is buffered so user could enter more than MAX_SIZE
do
{
c = fgetc(stdin);
if ( c != EOF && (isalpha(c) || isdigit(c))) // only consider "proper" characters
{
arr[count++] = (char)c;
}
}
while(c != EOF && c != '\n' && count < MaxLen); // EOF or Newline or MaxLen
getReverse( revArr, arr, count );
printf("%s\n", revArr);
return 0;
}
void getReverse(char dest[], char src[], int count)
{
int i = count - 1;
int j = 0;
while ( i > -1 )
{
dest[j++] = src[i--];
}
}
Dealing with strings is a rich source of bugs in C, because even simple operations like copying and modifying require thinking about issues of allocation and storage. This problem though can be simplified considerably by thinking of the input and output not as strings but as streams of characters, and relying on recursion and local storage to handle all allocation.
The following is a complete program that will read one line of standard input and print its reverse to standard output, with the length of the input limited only by the growth of the stack:
int florb (int c) { return c == '\n' ? c : putchar(florb(getchar())), c; }
main() { florb('-'); }
..or check this
#include <stdio.h>
#include <stdlib.h>
#define MAX 100
char *my_rev(const char *source);
int main(void)
{
char *stringA;
stringA = malloc(MAX); /* memory allocation for 100 characters */
if(stringA == NULL) /* if malloc returns NULL error msg is printed and program exits */
{
fprintf(stdout, "Out of memory error\n");
exit(1);
}
else
{
fprintf(stdout, "Type a string:\n");
fgets(stringA, MAX, stdin);
my_rev(stringA);
}
return 0;
}
char *my_rev(const char *source) /* const makes sure that function does not modify the value pointed to by source pointer */
{
int len = 0; /* first function calculates the length of the string */
while(*source != '\n') /* fgets preserves terminating newline, that's why \n is used instead of \0 */
{
len++;
*source++;
}
len--; /* length calculation includes newline, so length is subtracted by one */
*source--; /* pointer moved to point to last character instead of \n */
int b;
for(b = len; b >= 0; b--) /* for loop prints string in reverse order */
{
fprintf(stdout, "%c", *source);
len--;
*source--;
}
return;
}
Output looks like this:
Type a string:
writing about C programming
gnimmargorp C tuoba gnitirw

Resources