The first char of my array doesnt get printed out - c

I want to program a Hangman game, but before comparing strings etc. I just wanted to scroll through the array automatically to see if that works - it doesn't, well, not as I imagined.
Everything besides the very first character gets printed out, but why?
int gameWon = 0;
char secretWord[7][1] = {{"H"},{"A"},{"N"},{"G"},{"M"},{"A"},{"N"}};
char guessedChar;
while(gameWon != 1)
{
printf("Guess a single letter: ");
scanf("%s", &guessedChar);
for(int i = 0; i < 7; i++)
{
printf("%c\n", secretWord[i][0]);
}
}

You're using the wrong format specifier to scanf:
scanf("%s", &guessedChar);
The %s format specifier expects a char * which points to the first element of a char array and places a null terminated string at that location. What you passed in was the address of a single char. This caused scanf to write past the memory location of guessedChar, invoking undefined behavior. In this case, it manifested as a nearby variable getting overwritted, specifically the first element of the array secretWord.
Change this to use %c instead, which is for reading single characters. Also, be sure to put a space before it in the format string to absorb any whitespace characters left in the input buffer:
scanf(" %c", &guessedChar);

The type that you specify in scanf is wrong, you pass in an address to a character but the format specifier %s expects a string which will cause undefined behavior. My guess is that it affects the rest of your code.
Also the type of secretword seems a bit odd, why not just an array or string?
char secretWord[] = "HANGMAN";
scanf is not a good choice of reading from the keyboard, instead use fgets() and strip off the ending \n or like in your case, just read the first char. Then you don't need to deal with the fact that scanf leaves characters in the keyboard buffer.
while (... )
{
printf("Guess a single letter: ");
char buffer[128];
if (fgets(buffer,sizeof(buffer),stdin) != NULL)
{
for (int i = 0; i < strlen(secretWord); ++i)
{
if (buffer[0] == secretWord[i])
{
...
}
}

Related

Why for loop never ends?

int ln;
printf("how many letters are your name?\n");
scanf("%d", &ln);
printf("Ok...enter your name by characters: \n");
char name[ln];
for (int i = 0; i<=ln; i++){
scanf("%s", &name[i]);
}
This code should transform a name in the array but the for-loop never ends. Someone who can help me?
%s is scanning string so technically your whole name is considered as one element. So have to enter many strings . just replace %s by %c and code should be ready to use
"Why for loop never ends?"
First things first, I do not think that the loop is infinite. For me it seems that you are just confusing %s with %c and interpret the waiting for more input as loop that "never ends".
You didn´t provided sufficient ressources to rebuild your issue, though.
But let´s get started:
The %s conversion specifier of scanf() is for reading a string, not a single character. If you want to read a single character per iteration, use scanf("%c", &name[i]); or name[i] = getchar(); instead of scanf("%s", &name[i]); in the for loop.
Your loop condition i <= ln is faulty, as you attempt to write one character more than expected with it, because index counting starts at 0, not 1. Use i < ln instead.
A string needs to have a terminating null character at the end. name needs to have one element more than to just hold the letters of the input name. Also place name[ln] = '\0'; after the loop to insert a null character in the last element of VLA name.
Note:
If you want to read a variable amount of characters from stdin which is determined at run-time, you don´t need to read each character separate and stop until the counter reaches ln - 1.
Reading a string with a variable amount of characters is one point, where fgets() is more appropriate than scanf().
Use fgets (name, sizeof(name), stdin); which ensures that the read string plus the string-terminating null character will fit exactly into name and catch the name once.
int ln;
printf("How many letters are in your name?\n");
scanf("%d", &ln);
getchar(); // catching left newline from scanf.
char name[ln + 1]; // +1 for null character.
printf("Ok...enter your name: \n");
fgets(name, sizeof(name), stdin); // Will read the name and append the null character.
getchar(); // catching left newline from fgets.
in the for condition, try to remove that equality and see, because you are allocating ln bytes in name variable, so the variable i will start from 0 and go to ln-1
for (int i = 0; i<ln; i++){
scanf("%c", &name[i]);
}
also note im using %c here to scan character, %s scans string.
Because your for loop must run one more time to end . simply change
i<=ln
to
i<ln
Why for loop never ends?
Inside the loop, scanf("%s", &name[i]); attempts to read a name ln + 1 times, eventually attempting to save data outside name[] bounds.
Saving data outside name[] bounds is undefined behavior (UB). Anything may happen.
Loop not needed to read one line of input as a name and name[] too small.
//char name[ln];
//for (int i = 0; i<=ln; i++){
// scanf("%s", &name[i]);
//}
char name[ln+1]; // One more for a \0
if (scanf("%s", &name[i]) ==1) {
Success();
}
Recommend to not use scanf() and use fgets().
char name[ln+1+1]; / One more for a \n and 1 for a \0
if (fgets(name, sizeof name, stdin)) {
name[strcspn(name, "\n")] = '\0'; // lop off potential \n
Success();
}

2D array of characters, printing extra character over limit?

The output of code
I want to create an array of character in which there are 'n' rows and each row have a character. In the given code I asked the user to enter the number of rows(n) then I create a variable 'chr' and each row contain only one character. Then I asked the characters one by one and store them in their respective rows but when I take the print of those characters something strange happens. The first row which should only store one character of its own stores all the characters of different rows. Why? can anyone explain to me this?
#include <stdio.h>
int main(void) {
int n;
scanf("%d", &n);
char chr[n][1];
for (int i = 0; i < n; i++) {
printf("Enter the %d character?\n", i);
scanf("%s", chr[i]);
}
// printing
for (int i = 0; i < n; i++) {
printf("\n%s\n", chr[i]);
}
return 0;
}
The first row which should only store one character of its own stores all the characters of different rows. Why? can anyone explain to me this?
scanf("%s", chr[i]);
%s reads a whole string until it encounters a white space character, such as newline \n, and writes it (excluding the white space character) into the first dimension; not only one character.
You also forgot that since you are trying to read a string a \0 is automatically appended to each string, but since the declaration of chr there is just place for one character in a dimension, not two.
A multi-dimensional array is allocated continously in memory, which provides the effect that the \0 character for the string in the previous dimension is stored at the first and only character of the next dimension; in the next iteration scanf overwrites then this \0 character to store the second character but again writes the \0 of this string into the first an only object of the following dimension and goes so on and on for each iteration, which ends up in a complete mess of Undefined Behavior, plus the \0 of the last string is written beyond the bounds of the complete multi-dimensional array.
So you can´t even say that they were stored in just one dimension, which isn´t the case, even if it seems like it would.
For more information about Undefined Behavior look at this question:
Undefined, unspecified and implementation-defined behavior
Rather use
scanf(" %c", &chr[i][0]);
with the %c format specifier to read only one character per iteration and implement a white space character before the %cformat specifier to catch the newline \n left in stdin by the scanf consumption of the previous loop walkthrough or any leading white space.
Also, change:
for(int i = 0; i<n; i++) {
printf("\n%s\n", chr[i]);
to
for(int i = 0; i<n; i++) {
printf("\n %c \n", chr[i][0]);
The whole code shall then be:
#include <stdio.h>
int main(void) {
int n;
scanf("%d", &n);
char chr[n][1];
for(int i = 0; i<n; i++) {
printf("Enter the %d character?\n", i);
scanf(" %c", &chr[i][0]);
}
// printing
for(int i = 0; i<n; i++) {
printf("\n %c \n", chr[i][0]);
}
return 0;
}
as to answer why its printing the other caracters, they are directly behind each other in memory, and as others pointed out since you told it to print a string, it treats those chars in a row as one string (which is an array of chars) until it encounters a termination char.
so in memory this
char array[3][1] = {{'a'},{'b'}{'c'}};
looks just like this:
char array[3] ={'a','b','c'};
or this
char array[3] = {"abc"};
the array variable is a pointer to the address in memory where the first char is positioned, if you use [] you just jump sizeof(char) amount of bytes to the next char,
with the 2D array this is similar, the 1st bracket makes you jump sizeof(2darray[0]) bytes, which is in this case the same as sizeof(char) since length is 1

Scanning in strings into a 2D array in C

I need to take an input of 20 words entered by the user put those into a 2D array and print that out
my current code is
char array2[20][20];
int i;
for(i=0;i<20;i++)
{
printf("enter a word\n");
scanf(" %[^\n]",array2[i]);
}
for(i=0;i<colsize2;i++)
{
printf("\n");
for(j=0;j<rowsize2;j++)
{
printf("%c",array2[i][j]);
}
}
(I have no idea what %[^\n] is but it works better than %c or %s)
there are no compiler errors and the program will run but when it prints the array after all the words have been entered all I get is complete garbage
like
aȪ(M▒awn-US▒ e▒(<▒▒t/▒▒▒(5h▒tr:▒(
qh▒tdle__000
HW5.exe▒`wauld▒(▒&Oe,▒*a▒+a▒▒
so much so that it takes a bit of scrolling to get back to the start of my program
I do have more in this program that's not in my question but I'm 99% sure it wouldn't mess with what I have here but if you do want to see the rest just ask
I literally just started programming so I don't know diddly squat about it yet so if you could keep that in mind when you answer also this is for a school assignment so it doesn't need to be perfect it just has to get the job done
thanks to whoever answers this I've been grappling with this for hours
The format string
" %[^\n]"
^ note the leading space
means that scanf will first read and discard any number of leading whitespace characters and then match any sequence of characters which does contain a newline. scanf can potentially overrun the buffer it save the string into if the input string is too large for the buffer invoking undefined behaviour. The %s format specifier means scanf skips the leading whitespace characters and reads the input string till it encounters a whitespace at which point it appends a terminating null byte to the buffer it writes into and then returns.
Therefore, what you need is
char array2[20][20];
int i;
for(i = 0; i < 20; i++)
scanf("%19s", array2[i]);
for(i = 0; i < 20; i++)
printf("%s\n", array2[i]);
Initialize your array to 0:
char array2[20][20] = { 0 } ;
And then print the string not every character:
for(i=0;i<20;i++)
{
printf("%s",array2[i]);
printf("\n");
}

Using the scanf() function

I intend to modify each other letter of a particular string. But for the purposes of this program none of that occurs. So far I've grabbed a string from the user and stored it in userinput and intend to print it.
#include <stdio.h>
#include <string.h>
int main(void) {
char userinput[256] ="";
printf("Enter somthing to change:\n");
scanf("%s", &userinput);
printf("%s\n", userinput);
int k = 2; // This is just here to do something every time k is even
int j = strlen(userinput);
for (int i = 0; i < j; i++) {
if(k % 2 == 0) {
printf("%s", userinput[i]);
k++;
}
else {
printf("%s", userinput[i]);
k++;
}
}
}
The strlen() function however does not work on the userinput. I figure this is because strlen() is supposed to take the address of the first char of a string and then iterate until reaching a null char but scanf doesn't actually create a null char.
I couldn't figure out a way of adding the '\0' after the string without first knowing the length of the string.
How would I go about accessing the length of a stored character sequence if it's stored in an array?
This:
scanf("%s", &userinput);
should be:
scanf("%s", userinput);
The address of operator & is unrequired, and incorrect. Arrays decay to the address of their first element when passed to a function. scanf("%s") will append a null terminating character so it is unnecessary to explicitly insert one.
To prevent potential buffer overrun specify the maximum number of characters that scanf() should write to userinput. This should be one less than the size of userinput, leaving room for the terminating null character:
scanf("%255s", userinput);
The incorrect format specifier (which is undefined behaviour) is being used to print the characters of userinput: use %c not %s. This:
printf("%s", userinput[i]);
must be:
printf("%c", userinput[i]);
Change
scanf("%s", &userinput);
to
scanf("%s", userinput);
The & operator is not required in the case of String capture. The scanf() automatically appends the null character('\0') to the end of the string so int j = strlen(userinput); should work.
If you still want to calculate the length without this function efficiently here is the link How to calculate the length of a string in C efficiently?
Change this
scanf("%s", &userinput);
with
scanf("%s", userinput);
we have to use addresses for scanf:
If we will scan into an int a then we have to call scanf() with the address of a => &a
If we will scan into a double a then we have to call scanf() with the address of a => &a
But If we will scan data into with pointer (memory address) int *a; or char array char a[50]; then we have to call scanf() with the pointer or with the array without adding &
From the scanf() page
Depending on the format string, the function may expect a sequence of
additional arguments, each containing a pointer to allocated storage
where the interpretation of the extracted characters is stored with
the appropriate type. There should be at least as many of these
arguments as the number of values stored by the format specifiers.
Additional arguments are ignored by the function. These arguments are
expected to be pointers: to store the result of a scanf operation on a
regular variable, its name should be preceded by the reference
operator (&) (see example).
You're confused about types, as others have indicated. Using scanf and printf when you're confused about types is dangerous!
scanf("%s", &userinput);
The type of &userinput is char (*)[256], but scanf expects %s to correspond to a char *. Since the type expected and the type given differ and aren't required to have the same representation, the behaviour is undefined.
I figure this is because strlen is supposed to take the address of the
first char of a string and then iterate until reaching a null char but
scanf doesn't actually create a null char.
Wrong. scanf certainly does assign a null character, when you use the %s format specifier. That is, providing scanf doesn't encounter an error or EOF. On that note, you should probably check for errors from scanf:
if (scanf("%s", userinput) != 1) {
/* Insert error handling here */
}
... as you should with all standard library functions in C.
k is pointless. Your loop already increments i at the same frequency as k.
strlen returns a size_t. Make sure you store return values in the right types. If a function returns size_t, then you store the return value in size_t. If a function returns int, then you store the return value in an int. Got it? Whatever the return type is, is whatever type you use to store the return type. Use the manual to find that out.
printf("%s", userinput[i]);
There's that type confusion again. userinput[i] is a char. %s tells printf to expect a char *. When the argument is invalid, the behaviour is undefined. That may cause your program to malfunction. Consider printf("%c", userinput[i]); or printf("%s", &userinput[i]);.

Getting Debug Error in C

i am a learner of 'C' and written a code, but after i compile it, shows a Debug Error message, here is the code:
#include<stdio.h>
void main()
{
int n,i=1;
char c;
printf("Enter Charecter:\t");
scanf("%s",&c);
printf("Repeat Time\t");
scanf("%d",&n);
n=n;
while (i <= n)
{
printf("%c",c);
i++;
}
}
Pls tell me why this happens and how to solve it
The scanf("%s", &c) is writing to memory it should not as c is a single char but "%s" expects its argument to be an array. As scanf() appends a null character it will at the very least write two char to c (the char read from stdin plus the null terminator), which is one too many.
Use a char[] and restrict the number of char written by scanf():
char data[10];
scanf("%9s", data);
and use printf("%s", data); instead of %c or use "%c" as the format specifier in scanf().
Always check the return value of scanf(), which is the number of successful assignments, to ensure subsequent code is not processing stale or uninitialized variables:
if (1 == scanf("%d", &n))
{
/* 'n' assigned. 'n = n;' is unrequired. */
}
scanf("%s",&c); should be scanf("%c",&c);
The %s format specifier tells scanf you're passing a char array. You're passing a single char so need to use %c instead.
Your current code will behave unpredictably because scanf will try to write an arbitrarily long word followed by a nul terminator to the address you provided. This address has memory allocated (on the stack) for a single char so you end up over-writing memory that may be used by other parts of your program (say for other local variables).
I'm not sure you understood the answer to your other question: Odd loop does not work using %c
These format specifiers are each used for a specific job.
If you want to get a:
character from stdin use %c.
string (a bunch of characters) use %s.
integer use %d.
This code:
char c;
printf("Enter Character:\t");
scanf("%c",&c);
Will read 1 character from stdin and will leave a newline ('\n') character there. So let's say the user entered the letter A in the stdin buffer you have:
A\n
The scanf() will pull 'A' and store it in your char c and will leave the newline character. Next it will ask for your int and the user might input 5. stdin now has:
\n5
The scanf() will take 5 and place it in int n. If you want to consume that '\n' there are a number of options, one would be:
char c;
printf("Enter Character:\t");
scanf("%c",&c); // This gets the 'A' and stores it in c
getchar(); // This gets the \n and trashes it
Here is a working version of your code. Please see inline comments in code for fixes:
#include<stdio.h>
void main()
{
int n,i=1;
char c;
printf("Enter Character:\t");
scanf("%c",&c);//Use %c instead of %s
printf("Repeat Time\t");
scanf("%d",&n);
n=n;//SUGGESTION:This line is not necessary. When you do scanf on 'n' you store the value in 'n'
while (i <= n)//COMMENT:Appears you want to print the same character n times?
{
printf("%c",c);
i++;
}
return;//Just a good practice
}

Resources