Issue with saving characters in multidimensional array - c

i have a given Input of four scanf-strings which i want to save in a multidimensional array. I Don't know if i save the string right, but i can't just simply print the whole array or certain characters of it.
char getr[4][4];
for (z=0; z<4; z++){
scanf(" %99s", &getr[z]);
}
for (s=0; s<4; s++) {
printf("%s\n",getr[s]);
}
Input:
abcd
efgh
ijkl
mnop
Output:
abcdefghijklmnop
efghijklmnop
ijklmnop
mnop
what if i just want to print the second line or the fourth character of the first line? Does anybody know?

First, change as following:
scanf(" %99s", getr[z]); //getr[z] is the address to take the 4 characters string
To print out the second line:
printf("%s\n", getr[1]);
To print out the fourth character of the first line:
printf("%c\n", getr[0][3]); // %c is used here because just print one character.

To store 4-char strings, like your example input, you need 5-char arrays to leave room for the terminating null character:
char getr[4][5];
Your scanf() format string should also reflect the amount of space you have; %99s could read up to 100 bytes (99 chars plus the null), and you only have 5 (including the null, after the above change). Also, &getr[z] and getr[z] happen to give the same address, but the types of the pointers are different -- but getr[z] gives a char * which is appropriate in this case. So...
scanf(" %4s", getr[z]);
Those changes will already keep the strings from running together, so individual strings can be accessed as getr[0] through getr[3]. To print individual characters within a string, add an additional set of indexing brackets and use a function that prints a character rather than a string:
fputc(getr[0][2],stdout); /* print 3rd char in 1st string */
printf("%c",getr[1][3]); /* print 4th char of 2nd string */
The reason you were getting all your strings concatenated was because the null char from the earlier strings overflowed into the next char array, and was overwritten by the first char of the next string you read. The last string's null would have overflowed past your whole 2D array into whatever was next in memory (which is bad).

Related

C Arrays - Why is the last character in the array displaying, how do I get it to display only the first 5? [duplicate]

This question already has answers here:
How should character arrays be used as strings?
(4 answers)
Closed 2 months ago.
/* Variables */
int num;
char array[5]; // Array must also include NULL char
char new;
/* Accepting user input */
printf("Please enter 5 characters below:\n");
scanf("%c\r", &array[0]);
scanf("%c\r", &array[1]);
scanf("%c\r", &array[2]);
scanf("%c\r", &array[3]);
scanf("%c", &array[4]);
/* Displaying input as string */
printf("%s", array);
I am trying to create a basic program that creates a string that accepts chars one after the other. I know that arrays start at 0 and end with the null character so I made my array[5] so if I inputted "a" "b" "c" "d" "e" I would get the output string "abcde" plus the null character. Sometimes it works with one set of characters but not another. If I input "q" "w" "e" "r" "t" i might get the output "qwerta". How do I stop it from displaying that last character?
I understand that the reason why this character being displayed is that it is undefined and will show whatever value is at that memory location but I don't know how to fix it.
I have tried to include different escape sequences, putting spaces in the scanf and printf statements but what am I doing wrong?
You have a character array with size 5. You read a character into each of the five elements of the array. This does not leave space for the null character, and you do not explicitly set the last char equal to '\0'. Thus this is not a null terminated string, and printing it as a string with the %s specifier in printf has undefined behavior.

number and string during same input

hello ive got this simple program, where i need to imput a number, and 2-letter string, the string is working normally, but the number gets weird
here is the program
void main(){
int input_year=0;
char input_string[1];
scanf("%d %s", &input_year, input_string);
char temp1 = input_string[0];
char temp2 = input_string[1];
printf("%d", input_year);
printf("%c", temp1);
printf("%c", temp2);
}
input used: 20200405 RD number (whitespace) String
the temp1 and temp2 are ok, and do what i expect them to do, but the input_year prints 20200192 rather than 20200405.
You need to remember that strings in C are really called null-terminated strings. A string of even one single character need space for two characters to fit the null-terminator.
Also remember that the size provided in array declarations is the actual number of elements, not the top index. So when you define input_string as an array of a single element, that means it only have a single element, with index 0.
If you want to read a string containing two characters you need to define an array of three characters: The two characters in the string plus the null-terminator.
You also need to limit the number of characters that scanf will read, so users can't input arbitrarily long strings and cause buffer overflows.
In short:
// Place for two characters, plus null-terminator
char input_string[3];
// Limit the input to only two characters (not including null-terminator)
scanf("%d %2s", &input_year, input_string);
On another note, if you want to use the date input in any other way than a single number, I recommend you read it as separate year, month and day:
unsigned year, month, day;
char input_string[3];
scanf("%4u%u%2u %2s", &year, &month, &day, input_string);
Also note that I use unsigned as a type (and the corresponding scanf format) as the input can't and shouldn't be negative.
You should also really check what scanf returns, to make sure the input is valid.
And lastly, to better handle input validation, I recommend you use fgets to read the input into a large string. Then use e.g. sscanf (with checking return values) to attempt to parse the input.
Your input buffer is too small
char input_string[1];
That reserves space for one character. You need 3 in your case of 'rd'. The extra one is because c always adds a 0 at the end of a string. So you need
char input_string[3];
at least if you are sure its always 2 characters
Or maybe
char input_string[10];
if it could be larger. You can tell sprintf the max size you will accept like this (say 2 in your case)
scanf("%d %2s", &input_year, input_string);
-----------^

c - save then print out a string in 2d array in C

I'm trying to make a simple program from C to store a data then save it to 2d array there's 2 data stored in the 2d array. I think the saving code is work well, but when I try to print out the data stored in 2d array it crashes.
Here's my code :
#include <stdio.h>
int main(){
char data[2][3];
//input the data then save it in 2d array
printf("enter the first word: ");
scanf("%s", &data[0][0]);
printf("enter the second word: ");
scanf("%s", &data[1][0]);
//here is the problem when iam trying to print out the stored data in 2d array
printf("first word: %s\nsecond word: %s", data[0][0],data[1][0]);
}
You have 3 issues with your code.
First, and the one causing your code to crash is your final printf(). You passed in data[0][0] which is of type char to %s which takes a null terminated string. You have also need an extra new line at the end. Change it to:
printf("first word: %s\nsecond word: %s\n", data[0], data[1]);
Second, your second dimension of your array is only 3. This means you can only store strings of size 3 or less. Accounting for the null terminator at the end, it's just a 2 character array. Change the second dimension to a bigger number (i.e. data[2][50]).
Third, &data[0][0] is redundant. You are dereferencing a pointer then making it a pointer again. Just do data[0] and data[1] in your scanf().
About your confusion of 2d char arrays
I think you are confused about what char arrays are and what c-strings are. A char array is an array of char. "Bill", for example, would be a char array where 'B' will be the index 0, 'l' will be index 3, and a null ternimator '\0' will be the last index to tell the machine that this is the end of the string.
A 2d char array would be an array of those strings (e.g. "Bill") like "Bill", "Bob", "Alice" etc. If you want to also keep track of not only people's names, but also their addresses, phones etc, you might need a 3d array.
The 3d array will look something like data[2][4][50]. Where the first level are the people you want to keep track of. The second level are the attribute of a specific person (name, address etc.). Third level will be an array of characters (char) that makes up an attribute about a person.
Clearing one thing...
Pass the address of a character array not the address of a char.
scanf("%s", data[1]);// same as &data[1][0]
Here you will see that the passing the address of the char variable also works because it is basically coincides with the address of the char array.
Error lies somewhere else...
Also you should pass the address of the char array to the printf.
printf("first word: %s\nsecond word: %s\n", data[0], data[1]);
Or as it is pointed out in the line before..yes you got it right..this also works
printf("first word: %s\nsecond word: %s\n", &data[0][0], &data[1][0]);
And as you know there will be 2 characters use scanf("%2s",data[1]).
So where did I do wrong?
"%s" expects a char* and what you passed to it is char. That's why it ran into error. Yes, it considered that char value to be an address and tried to access it and it invoked undefined behavior.
If you want to print characters then you will use different format specifier:
printf("%c",data[1][0]);
Few things to point out:-
You are only considering 2 length char arrays or 2 length strings.
To remind you once more %c deals with arguments of type char and %s deals with arguments of type char*. (That's why the distinction in printf).
scanf() is like a parser. In case it fails to parse something it skips it. There are better ways to get input fgets() etc.

Confusion about strings in C

Char arrays have continuously confused me in C.
Here is the following code:
char tcp_port[100], udp_port[6];
tcp_port[99] = '\0'; udp_port[5] = '\0';
fscanf(fp, " tcp_port=%s", tcp_port);
fscanf(fp, " udp_port=%s", udp_port);
printf("%s\n", tcp_port); printf("%s\n", udp_port);
This works and prints out the right number. However, since tcp_port has 100 elements, how do those just disappear when printing? The port is only 5 characters long and the last element is null terminated. Does printf just ignore those unintialized elements, and do those uninitialized elements contain random data?
Yes, printf() only prints the characters up to the first \0 character. All C string functions do this. They also automatically append that \0 character when necessary, like the scanf() function there. That's why it's called a "0-terminated string".
The other elements can contain anything and they will be completely ignored. In practice, they usually contain random junk, but it depends on a variety of factors.
Note that when you allocate memory you must keep that \0 character in mind. Your tcp_port string can only at most 99 characters, because the last one must be 0.

Why the complete character array is getting printed not the first character?

This is the source code
char target[80]="hello", *tar;
tar=&target;
printf("%s",tar); //printing hello
tar is getting the address of target[0] then why it is printing the whole character array.
when u say %s and specify a starting memory(or any intermediate) of the string it gets printed till it encounters '\0' character.
consider
char *name = "Hello";
will be stored internally as
Hello\0
so if u need a single character go for %c.
Use %c to print a single character and %s is used to print a string.
C strings are null terminated. When you pass the address of the first character in an array of characters representing a string to printf and tell it to format the output as a string using %s, it will print all of the characters beginning at the address of the first character until a null (NUL) character, '\0', is reached.
%s indicates printing characters between the character 'tar' points to and next '\0' .
printf("%c",*tar);
will print what you need.

Resources