I can't print the first index of the Character Array? [closed] - c

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 14 days ago.
Improve this question
#include <stdio.h>
#include <stdlib.h>
int main()
{
char A[100];
char c;
scanf("%s", &A);
while ((getchar()) != '\n');
scanf("%c", &c);
int i, count = 0;
for(A[i] = 0; A[i] != c; i++) {
count++;
}
//printf("%d",count);
for(i = 0; i < count; i++) {
printf("%c", A[i]);
}
return 0;
}
I want to print (ca) if I enter input String A as (cat) and character c as (t ).But I am getting output as (a) the first word is not printing .Please tell me what is wrong with my code.

When you program in C it's very valuable to look at the warnings you get from the compiler. If you use Windows the Visual C compiler should output something like this, assuming your program is stored in test.c:
C:\Users\Public>cl test.c
Microsoft (R) C/C++ Optimizing Compiler Version 19.31.31107 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
test.c
C:\Users\Public\test.c(12) : warning C4700: uninitialized local variable 'i' used
Microsoft (R) Incremental Linker Version 14.31.31107.0
Copyright (C) Microsoft Corporation. All rights reserved.
/out:test.exe
test.obj
On Linux, using GCC, you get a similar warning but in this case you need to add the option -Wall which enables many useful warnings:
$ gcc -Wall test.c
test.c: In function ‘main’:
test.c:8:13: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[100]’ [-Wformat=]
8 | scanf("%s", &A);
| ~^ ~~
| | |
| | char (*)[100]
| char *
test.c:12:14: warning: ‘i’ is used uninitialized in this function [-Wuninitialized]
12 | for(A[i] = 0; A[i] != c; i++) {
| ~~~~~^~~

for(A[i] = 0; A[i] != c; i++)
This assigns 0 to the first position in A (A[i] = 0). You probably wanted to write
for(i = 0; A[i] != c; i++)
instead.
There are some other problems with the code as well, especially in error handling, but I'll let you figure those out.

It seems you've made one big mistake, and it's in the first for loop:
for(A[i] = 0; A[i] != c; i++) {
count++;
}
Here, you're initializing A[i] to 0. Now, let's see what's wrong with that: at that point in the code, i is not initialized, so it has an arbitrary value (like -53451561). This is bad, because you're trying to access the -53451561th element of the array, which is never good. Of course, i could be 0, which means that you'll get away with setting the first character of A to 0, but the point is that you don't know the value of i and shouldn't use it before you initialize it.
Next, this is not really how you write a for loop, and this could very much be a mistake. What you should've written is i = 0. This way you start from i = 0, and use it as a counter in the loop (since the last statement in the for loop is i++). As a rule of thumb, the variable in the first statement of the for is the same as the last one.
Lastly, the condition is correct, but you should account for the end of the string \0. So, the final form of the for loop looks something like this:
for(i = 0; A[i] != c && A[i] != '\0'; i++) {
count++;
}
Now, there's a minor issue that has been pointed out by other comments: you scanf strings without the reference & operator:
scanf("%s", mystring);
This is because the string is already a pointer itself, so scanf can already write the result to the pointer, without needing a pointer to the pointer.
One more thing:
You could just print the characters in the first loop, which will improve the performance of your program twice.
Finally, this is how you program could look. Please, copy this only if you understand what I've explained above:
char A[100];
char c;
int i;
scanf("%s", A);
while ((getchar()) != '\n');
scanf("%c", &c);
for(A[i] = 0; A[i] != c; i++) {
printf("%c", A[i]);
}

Related

Why doesn't scanf with character set format read input in a for loop?

While trying to get newline character as input using scanf and display it as output as this discussion suggests, I tried the following code,
#include <stdio.h>
void main()
{
int n;
printf("Loop:\n");
scanf("%d",&n);
for (int i = 0; i < n; ++i)
{
char in[28];
scanf("%27[^\n]%*c",&in);
printf("%s\n",in);
}
}
During execution, inside the for loop the input stream doesn't accept any inputs and instead displays n smiley faces. Is this because of the trailing newline character after reading n?
Beyond the type mismatch, the reason scanf("%27[^\n]%*c",&in); does not read extra input from the user is there is a pending newline left by scanf("%d",&n);. scanf() fails because there is no match for the character set and the newline is not consumed by %*c because the previous mismatch stops the scan.
Here is a modified version:
#include <stdio.h>
int flush_input(void) {
int c;
while ((c = getchar()) != EOF && c != '\n')
continue;
return c;
}
int main() {
int n;
printf("Loop:\n");
if (scanf("%d", &n) != 1)
return 1;
flush_input();
for (int i = 0; i < n; ++i) {
char in[28];
if (scanf("%27[^\n]", in) != 1) {
// blank line or EOF
*in = '\0';
}
printf("%s\n", in);
if (flush_input() == EOF)
break;
}
return 0;
}
How to compile any C program as a beginner: What compiler options are recommended for beginners learning C?
Following this advise and compiling with gcc gives 2 problems:
<source>:2:6: error: return type of 'main' is not 'int' [-Wmain]
2 | void main()
| ^~~~
<source>: In function 'main':
<source>:11:21: error: format '%[^
' expects argument of type 'char *', but argument 2 has type 'char (*)[28]' [-Werror=format=]
11 | scanf("%27[^\n]%*c",&in);
| ~~~~~^~ ~~~
| | |
| char * char (*)[28]
The first reported error is because void main() is an implementation-defined form of main() which isn't suitable for gcc unless you explicitly compile for embedded systems or the like. Switch to int main (void).
The second reported error says that the conversion %c expected a parameter of type char*. You gave it a parameter of type char (*)[28]. Huh, what is that? Well, it is a pointer to an array of 28 char. Not the same thing and not what you want, but what you get if you do &in instead of in.
Luckily, viewing multiple lines of the gcc output gives you the exact location of the bug, after which you will find the bug in seconds:
11 | scanf("%27[^\n]%*c",&in);
| ~~~~~^~ ~~~
| | |
| expect BUG HERE FIX ME
Now if you follow the above guidelines, you should be able fix the next trivial bug that the compiler has already found.

please help me to find the error in this C code [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I am a beginner to c language. Please help me to find the error of the code as it gives a complilation error on the display.
#include <stdio.h>
#include <string.h>
void main()
{
char i;
char arr[23];
printf("Enter your name? \n");`
scanf("%c",&arr[i]);
for(int v=0;v<=strlen(arr);v++)
{
printf("%c",arr[v]);
}
}
Your code has several issues, not only one:
1.
You use the wrong format specifier %c to catch a single character instead of %s to catch a string:
char arr[23];
printf("Enter your name: \n");`
scanf("%c",&arr[i]);
Rather use scanf("%s",arr); or even better scanf("%Ns",arr); where N stands for the maximum number of characters to be entered. Note that you need one element for the string-terminating null character, so it requires to be at least one character less than the char array is consisted of.
You can also use fgets(arr,23,stdin) which is preferred for consuming strings from the standard input because it is more safe as it requires you to provide the maximum amount of characters to read (counting the null character too) and also reads white space separated words as part of the string by default.
2.
i is not initialized to any value, so:
scanf("%c",&arr[i]);
causes undefined behavior.
3.
Furthermore you try to get a string length by using strlen() as part of the condition expression of the for loop:
for(int v = 0; v <= strlen(arr); v++)
although there is no valid string in arr which causes also undefined behavior.
As a side note here: It is more efficient to use strlen() only once before the for loop, store its return value in an object of an appropriate type (size_t is the type of the return value of strlen()) and use that object in the condition of the for loop instead of executing strlen() before each iteration.
4.
Next thing is that you attempt to print characters inside the for loop which aren´t provided/initialized to arr:
for(int v = 0; v <= strlen(arr); v++)
{
printf("%c",arr[v]);
}
5.
The for loop with the condition v <= strlen():
for(int v = 0; v <= strlen(arr); v++)
runs one time more than expected and prints the null character which is redundant since the null character is not printable.
Rather use v < strlen() or according to point 3:
size_t len = strlen(arr);
for(int v = 0; v < len; v++)
6.
The return value of main shall be int, not void.
7.
There is a trailing apostrophe after the printf() call:
printf("Enter your name: \n");`
Rather use:
#include <stdio.h>
int main()
{
char arr[23];
printf("Enter your name: \n");
scanf("%22s",arr);
printf("%s",arr);
}
Online Example
if you want to print out the string entered as whole at once, or:
#include <stdio.h>
#include <string.h>
int main()
{
char arr[23];
printf("Enter your name: \n");
scanf("%22s",arr);
size_t len = strlen(arr);
for(int v = 0; v < len; v++)
{
printf("%c",arr[v]);
}
}
Online example
if you want to print each character separate.
Your error is not really an error. You have an extra character in this lane:
printf("Enter your name? \n");`
It should be:
printf("Enter your name? \n");
There is a ` at end of the line
printf("Enter your name? \n");`
note you are using uninitialized int i here scanf("%c",&arr[i]); which is wrong.
also with scanf("%c",&arr[i]); you can only scan one character for string arr which I think is not your purpose.
you can use scanf("%s",arr[i]); instead to appropriately scan an string .
also note when ever you are scanning string char by char you have to add terminator \0 to the end of your string.after scanning characters until element i-1 of array add \0 to element i like this arr[i]=\0;.
since your string isn't terminated appropriately strlen won't work well.
also note you should print elements of string while v<strlen(arr) the last char should be \0 so you should use in for(int v=0;v<=strlen(arr);v++)
also pay attention to use int main not void main.
look:
void main()
{
char arr[23];
printf("Enter your name? \n");
scanf("%s",arr);
for(int v=0;v<strlen(arr);v++)
{
printf("%c",arr[v]);
}//or instead of loop use printf("%s",arr);
}

Printing from a file and storing in arrays. [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 4 years ago.
Improve this question
Im trying to read from a file into an array, which is shown in the first for loop. This part of my script works, however i want the answers that the user gives to be copied into the array q.a in the q structure. and the at the end of the script the questions and answers given printed off. Can anyone shed some light on why this isn't working for me?
struct qa{/
char q[40][250];
char a40][250];
};
int main()
{
int a, i, k, l, j;
FILE *fp;
fp = fopen("quest.txt", "r");
struct qa q;
for(i>0;i<=11;i++){
fgets(q.q, 250, (FILE*)fp);
printf("%s", q.q);
scanf("%s", q.a[l][j]);
}
for (i=0;i<11;i++){
strncpy(q.a[j], q.q[k], 250);
}
for (i = 0; i < 11; i++){
printf("%s/n", q.a[l][j]);
}
I get a segmentation fault error when i try and run the script that only started happening when i put the strncpy for loop in.
First of all you never initialize your values : i j k l are never initialized and a isn't even used.
Then you're trying with scanf("%s", q.a[l][j]); to put a char * into a char.
See stacktrace
For debugging purposes install and use valgrind/gdb if you're into cli or any debuggers in your IDE, it will be easier
This is the code I used, if you want to know which lines point to which line of code
Change scanf("%s", q.a[l][j]); to scanf("%s", q.a[l]); and do the same for the last printf
Also remember to compile with flags like -W -Wall -Wextra so that you can get more warnings from the compiler, it can detect most of your mistakes.
This is awful:
for(i>0;i<=11;i++){
fgets(q.q, 250, (FILE*)fp);
printf("%s", q.q);
scanf("%s", q.a[l][j]);
}
with one inconsistency per line!
for(i>0;i<=11;i++) the first element of a for is for assignation so it should never contain a comparison. You want for(i=0; i<11; i++)
fgets(q.q, 250, (FILE*)fp); - q.q is an array of char arrays, when what is expected by fgets is an array of characters. It should be fgets(q.q[i], 250, (FILE*)fp);.
printf("%s", q.q); invokes undefined behaviour, because q.q is an array of array of chars when %s expects a char pointer. It should be printf("%s", q.q[i]);
scanf("%s", q.a[l][j]); %s expects a pointer to an array of characters, and you give it the value of a single character! What you want is scanf("%249s", q.a[i]);
This means nothing:
for (i=0;i<11;i++){
strncpy(q.a[j], q.q[k], 250);
}
j and k are uninitialized automatic variables, so their value is anything. In short you are writing random values at random memory location!
Even the last part is poor:
for (i = 0; i < 11; i++){
printf("%s/n", q.a[l][j]);
}
l is still uninitialized, the end of line is \n with a backslash and not a straight slash, and %s still expects a char pointer... If you want to print the questions and answers, just do:
for (i = 0; i < 11; i++){
printf("%s\n%s\n\n", q.q[i], q.a[i]);
}
it will give you the question on a line, the answer on the following one, and the empty line before next bloc.
TL/DR: you really should consider learning the basics of C language...

What's wrong with my c code? (it's probably the malloc call) [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
When I run this code, I get a segmentation fault. I'm sure I'm doing the pointers wrong, but I'm not sure why or how to fix it.
I also included the question I'm trying to answer in picture form.
#include <stdio.h>
#include <stdlib.h>
char * repeat_characters(char *s, int n) {
printf("%s", *s);
char temp;
int length = 0;
int i = 0;
int j = 0;
int k = 0;
char * newString;
while(s[length]) {
length++;
printf("%d", length);
} // finds length of string
newString = (char*) malloc(length*n*sizeof(char));
while(i++ < i*n) {
temp = s[i];
while (j++ < n) {
newString[k] = temp;
printf("%c", temp);
k++;
}
}
printf("%s", newString);
return newString;
}
int main () {
char * string[100];
int numReps = 0;
printf("Enter a string: ");
scanf("%s", string);
printf("\nEnter number of repetitions: ");
scanf("%d", &numReps);
repeat_characters(*string, numReps);
return 0;
}
One of your jobs as a questioner is to shorten your program to the minimum that demonstrates a problem. For instance, the following would give a segmentation fault:
#include <stdio.h>
char * repeat_characters(char *s, int n) {
printf("%s", *s);
return NULL;
}
int main () {
char * string[100];
scanf("%s", string);
repeat_characters(*string, 0);
return 0;
}
Lots of kinds of problems could be pointed out by compiler warnings. So turn those warnings on. If you're using gcc, then try something like gcc -Wall -Wextra -Werror main.c (or look in your compiler's documentation.)
(The -Werror will turn the warnings into errors, and keep you from accidentally ignoring a warning, which I'd say is a good habit for both learners and experts alike.)
printf("%s", *s);
format '%s' expects argument of type 'char*', but argument 2 has type 'int'
Here you have a parameter char *s. Depending on context could either be a pointer to a single character, or a pointer to the first character of a multiple-character sequence.
C strings operate on the convention that it's a multiple character sequence, and that the range of characters is eventually terminated by a '\0' (or 0-valued character). So when you call printf you must be sure that the character pointer you pass in is to such a validly formed sequence.
You are passing in *s, which dereferences the pointer-to-a-character to make it into a single character. If you want to print a single character, then you'd need to use %c, e.g. printf("%c", *s);. But you want to print a C string, so you should drop the dereferencing * and just say printf("%s\n", s). (You will likely want \n to output a newline, because otherwise your prints will all run together.)
(Note: The reason C without warnings didn't complain when you passed a character where a character pointer was expected is due to the "weirdness" of functions like printf and scanf. They don't have a fixed number or type of arguments that they take, so there is less checking...warnings help pick up the slack.)
scanf("%s", string);
format '%s' expects argument of type 'char*', but argument 2 has type 'char**'
Here you have the problem that you've declared s as char * string[100];, which is an array of character pointers, not an array of characters. The duality of a C array being able to behave like a pointer to its first element takes some getting used to, but if you say char string [100]; then string[0] is a char and string can "decay" to a char* synonymous with &string[0]:
Is an array name a pointer?
while(i++ < i*n)
operation on 'i' may be undefined
The compiler is making a technical complaint here, about modifying the variable i in an expression that also uses i. It's warning about whether the i in i*n would see the value before or after the increment. Avoid this kind of expression...and when-and-if the time comes where you care about what you can and can't do like this, read about sequence points.
But put that aside. What did you intend here? Take the nuance of ++ out of it...what about just while (i < i * n)? When would that be false? Why would it be relevant to solving the problem?
Look through your code and perhaps try commenting it more. What are "the invariants", or the things that you can claim about a variable that would be true on each line? If you were asked to defend why the code worked--with no compiler to run it to see--what would be giving you the certainty that it did the right thing?
Then step through it with a debugger and examples, and check your intuition. If you step over a line and don't get what you expect, then that's when it may be time to start thinking of a question to ask which draws the focus to that line.
There's other issues raised in the comments (for instance, that your malloc() doesn't include space for the terminator, and even once you add in 1 for that space you still have to write a '\0' into it...). Generally speaking your program should perform as many free()s as it does malloc()s. Etc. But hopefully this points you in the right direction for the assignment.

Taking a string as input and storing them in a character array in C [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions must demonstrate a minimal understanding of the problem being solved. Tell us what you've tried to do, why it didn't work, and how it should work. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I am stumped on how to store strings in an array in C, with each character kept separately. As an example, if the user inputs hellop, I want to store it in a given array, say userText, with userText[0] = h, userText[1] = e, userText[2] = l, and so on. I know this is easy stuff, but I'm still new. So if anyone could help, it would be great. Please explain how to do this using pointers.
#include<stdio.h>
void main()
{
char a[10],c;
int i=0;
while((c=getchar())!='\n')
{
scanf("%c",&a[i++]);
c=getchar();
}
for(i=0;i<11;i++)
printf("%c",a[i]);
}
The program outputs some garbage value (eoeoeoeo\363) when I type in hellop.
To read input I recommend using the fgets function. It's a nice, safe alternative to scanf.
First let's declare a buffer like so:
char user_input[20];
Then we can get user input from the command line in the following manner:
fgets(user_input, 20, stdin);
This will store a maximum of 20 characters into the string from the standard input and it will ensure it is null-terminated. The fact that we've limited the input to the size of the array declared earlier ensures that there's no possibility of buffer overruns.
Then let's clear the pesky newline that's been entered into the string using strlen:
user_input[strlen(user_input) -1] = '\0';
As strlen returns the size of the string up to the null terminator but without it, we can be sure at that position lies the newline character (\n). We replace it with a null-terminator(\0) so that the string ends there.
Finally, let's print it using printf:
printf("The user has entered '%s'\n", user_input);
To use fgets and printf you will need to declare the following header:
#include <stdio.h>
For strlen we need another header, namely:
#include <string.h>
Job done.
P.S. If I may address the code you've added to your question.
main is normally declared as int main rather than void main which also requires that main returns a value of some sort. For small apps normally return 0; is put just before the closing brace. This return is used to indicate to the OS if the program executed successfully (0 means everything was OK, non-zero means there was a problem).
You are not null-terminating your string which means that if you were to read in any other way other than with a careful loop, you will have problems.
You take input from the user twice - once with getchar and then with scanf.
If you insist on using your code I've modified it a bit:
#include<stdio.h>
int main()
{
char a[10];
int i=0;
while( (a[i++]=getchar()) != '\n' && i < 10) /* take input from user until it's a newline or equal to 10 */
;
a[i] = '\0'; /* null-terminate the string */
i = 0;
while(a[i] != '\0') /* print until we've hit \0 */
printf("%c",a[i++]);
return 0;
}
It should now work.
To read a string into char array:
char *a = NULL;
int read;
size_t len;
read = getline(&a, &len, stdin);
//free memory
free(a);
Your code is this (except I've added a bunch of spaces to improve its readability):
1 #include <stdio.h>
2 void main()
3 {
4 char a[10], c;
5 int i = 0;
6 while ((c = getchar()) != '\n')
7 {
8 scanf("%c", &a[i++]);
9 c = getchar();
10 }
11 for (i = 0; i < 11; i++)
12 printf("%c", a[i]);
13 }
Line-by-line analysis:
OK (now I've added the space between #include and <stdio.h>).
The main() function returns an int.
OK (it is hard to get an open brace wrong).
Since the return value of getchar() is an int, you need to declare c separately as an int.
OK.
Needs to account for EOF; should be while ((c = getchar()) != EOF && c != '\n'). You're still very open to buffer overflow, though.
OK.
Not OK. This reads another character from standard input, and doesn't check for EOF.
Not OK. This too reads another character from standard input. But when you go back to the top of the loop, you read another character. So, as things stand, if you type abcdefg at the program, c is assigned 'a' in the loop control, then a[0] is assigned 'b', then c is assigned 'c', then the loop repeats with a[1] getting 'e'. If I'd typed 6 characters plus newline, the loop would terminate cleanly. Because I claimed I typed 7 characters, the third iteration assigns 'g' to c, which is not newline, so a[2] gets the newline, and the program waits for more input with the c = getchar(); statement at the end of the loop.
OK (ditto close braces).
Not OK. You don't take into account early termination of the loop, and you unconditionally access a non-existent element a[10] of the array a (which only has elements 0..9 — C is not BASIC!).
OK.
You probably need to output a newline after the for loop. You should return 0; at the end of main().
Because your input buffer is so short, it will be best to code a length check. If you'd used char a[4096];, I'd probably not have bothered you about it (though even then, there is a small risk of buffer overflow with potentially undesirable consequences). All of this leads to:
#include <stdio.h>
int main(void)
{
char a[10];
int c;
int i;
int n;
for (i = 0; i < sizeof(a) && ((c=getchar()) != EOF && c != '\n')
a[i++] = c;
n = i;
for (i = 0; i < n; i++)
printf("%c", a[i]);
putchar('\n');
return 0;
}
Note that neither the original nor the revised code null terminates the string. For the given usage, that is OK. For general use, it is not.
The final for loop in the revised code and the following putchar() could be replaced (safely) by:
printf("%.*s\n", n, a);
This is safe because the length is specified so printf() won't go beyond the initialized data. To create a null terminated string, the input code needs to leave enough space for it:
for (i = 0; i < sizeof(a)-1 && ((c=getchar()) != EOF && c != '\n')
a[i++] = c;
a[i] = '\0';
(Note the sizeof(a)-1!)

Resources