Printing first index in array prints every index with C - c

I am starting to learn C and have a question about arrays.
Here I have a 2-dimensional simple array of characters:
char memory[100][6];
...
// populate indexes
and here I try to print out the first row:
puts(memory[0]);
Here is the output. Why does every row print out?
00P00300P10404P1ZZZZ0000ZZ0010
I come from Java where if you run the same code you will only get the first row. Am I missing something or is this just how C handles arrays? If so, how can I just get the first row?

The puts function is strictly for C-style strings. If you pass it a pointer to something other than a C-style string, garbage is likely to result. How are you expecting it to know how many characters to output?

Related

Copying and comparing individual element from 2D array to another array in C

char first_array[5][4] = {"aaa","bbb","ccc","ddd","eee"};
char second_array[1][4];
How would I copy, for example, the third element in first_array ("ccc") and save it to second_array?
The syntax below is clearly wrong, but this is what I'm asking for:
second_array[0] = first_array[2];
Also, after copying, I also want to know how to compare elements in the two arrays. Again, the syntax below might be wrong, I'm just explaining what I'm trying to do:
if(second_array[0] == first_array[2]){ printf("yes"); } //should print yes
You can't assign to arrays in c, you can fill arrays with some library functions like strcpy(), so
second_array[0] = first_array[2];
would be
strcpy(second_array[0], first_array[2]);
you must however ensure that the destination array fits the number of characters you are copying to it.
If you try to compare two strings in c, you can't do it through the == operator, because strings in c are arrays of char which contain a sequence of non-nul characters followed by a nul character, so if you write this
if (second_array[0] == first_array[2])
even when you succeeded at copying the data, the result will be most likely false, because you are not comparing the contents of the arrays, but their addresses, so to compare them correctly there is also a function strcmp() then the correct way of comparing the strings is
if (strcmp(second_array[0], first_array[2]) == 0)
The functions above require you to include the string.h header, and also that the passed strings are strings in the c sense, i.e what I described above.
I was recently trying to do this, as well: it is not possible to do this sort of direct assignment in C.
When you write first_array[0], the compiler will read that as an address which points to the first element (character) of first_array[2], not the entire string. When you run the assignment, if it were to work, it would only set the first character.
The easiest way is to use strncpy or memcpy (or a loop to cycle through the string.

C language, char=char with unexpected results

Hi everybody and thanks in advance for any help, this is the situation:
#define N 12
[..]
char vect[N][2];
char strng[2];
[..]
vect[i][0]=strng[2]; //this two lines are in a simple for cycle
vect[i][2]=strng[0];
Now, if in string[2] I have "c 2", what I expect in vect[i][0] is '2' and in vect[i][1] 'c'.
I use code::blocks and watching vect I have instead "2#", but it could be "2À" as well.
Can you help me? Where am I wrong?
Array indexes goes from zero up to the size minus one. So using e.g. strng[2] you access the third entry in the two-entry array. Accessing an array out of bounds leads to undefined behavior and the data will be indeterminate.
You should also remember that all strings in C are one more character than reported by e.g. strlen, and that extra character is a special terminator character. So if you want a two-character string, you really need three characters: Two for the string, and one for the terminator.
Rewrite these statements
vect[i][0]=strng[2]; //this two lines are in a simple for cycle
vect[i][2]=strng[0];
the following way
vect[i][0]=strng[1]; //this two lines are in a simple for cycle
vect[i][1]=strng[0];
provided that string contains two characters { 'c', '2' }.
Take into account that array string can not have string literal "c 2", because you defined it as
char strng[2];
that is it can contain only two characters.
If you want that the array would contain indeed "c 2" then you have to define it either as
char strng[3];
or as
char strng[4];
if you want to include the terminating zero.
In this case you may write
vect[i][0]=strng[2]; //this two lines are in a simple for cycle
vect[i][1]=strng[0];
Assuming strng literally contains "c 2", then your memory is the issue. strng[2] contains 3 cells iirc. 2 for holding chars and then a null terminator (ie \0). so when you try to access strng[2], (which you cant because you can only go to N-1 cells, where N is the number allocated for it) it contains undefined results, since it isnt null terminated and you are reaching beyond memory you allocated

Array fill in C

I have this problem with a lot of arrays in my program, and I can't understand why. I think I miss something on array theory.
"Someone" adds at the end of my arrays some sort of char characters such as ?^)(&%. For example if I have an array of lenght 5 with "hello", so it's full, sometimes it prints hello?()/&%%. I can undesrtand it can occur if it's of 10 elements and i use only 5, so maybe the other 5 elements get some random values, but if it's full, where the hell gets those strange values?
I partially solve it by manaully adding at the end the character '\0'.
For example this problem occurs, sometimes, when I try to fill an array from another array (i read a line form a test file with fgets, then I have to extract single words):
...
for(x=0;fgets(c,500,fileb);x++) { // read old local file
int l=strlen(c);
i=0;
for (k=0;k<(l-34);k++) {
if(c[k+33]!='\n') {
userDatabaseLocalPath[k]=c[k+33];
}
}
Thanks
Strings in C are terminated by a character with the value 0, often referred to as a character literal, i.e. '\0'.
A character array of size 5 can not hold the string hello, since the terminator doesn't fit. Functions expecting a terminator will be confused.
To declare an array holding a string, the best syntax to use is:
char greeting[] = "hello";
This way, you don't need to specify the length (count the characters), since the compiler does that for you. And you also don't need to include the terminator, it's added automatically so the above will create this, in memory:
+-+-+-+-+-+--+
greeting: |h|e|l|l|o|\0|
+-+-+-+-+-+--+
You say that you have problems "filling an array from another longer array", this sounds like an operation most referred to as string copying. Since strings are just arrays with terminators, you can't blindly copy a longer string over a shorter, unless you know that there is extra space.
Given the above, this code would invoke undefined behavior:
strcpy(greeting, "hi there!");
since the string being copied into the greeting array is longer than what the array has space for.
This is typically avoided by using "known to be large enough" buffers, or adding checks that manually keep track of the space used. There is a function called strncpy() which sort of does this, but I would not recommend using it since its exact semantics are fairly odd.
You are facing the issue of boundary limit for the array.. if the array is of size 5 , then its not necessary that the sixth location which will be \0 be safe.. As it is not memory reserved/assigned for your array.. If after sometime some other application accesses this memory and writes to it. you will lose the \0 resulting in the string helloI accessed this space being read. which is what you are getting.

how to form an array of numbers , taken input from a file in C

The program should be able to make an array of numbers from a text file which reads like this
The data is given as this
123 2132 1100909 3213 89890
my code for it is
char a;
char d[100];
char array[100];
a=fgetc(fp) // where fp is a file pointer
if (a=='')
{
d[count1]='/0';
strcpy(&array[count],d);
count=count+1;
memset(d,'\0',100)
count1=0;
}
else
{
d[count1]=a;
count1=count1+1;
}
a=fgetc(fp);
i am getting segmentation fault now . want to store each number in the array so that i can do sorting on it
Your (first) problem is here:
d[count1]='/0';
strcpy(&array[count],d);
You have written '/0', which isn't what you think it is. Assuming you meant '\0' (a null char literal), then you appear to be trying to manually terminate the string d before calling strcpy(). The problem is that what actually gets written to d is not a null byte, and so d is not null-terminated, and then strcpy() goes off and starts reading random memory after it, and copying that memory into array, until either the reading or the writing ends up outside of memory you're allowed to access, and you get a segmentation fault.
You also have some confusion about that array is. It's declared as an array of 100 chars, but you're treating it like it's an array of strings. Perhaps you meant to declare it as char *array[100] ?
Hmm...as a first approximation, to read a single number, consider using fscanf("%d", &number);. To store the numbers you read, you'll probably want to create an array of numbers (e.g., int numbers[100];). To read more than one number, use a loop to read the numbers into the array.
Sidenote: fscanf isn't particularly forgiving of errors in the input (among other things) so for production code, you probably want to read a string, and parse numbers out of that, but for now, it looks like you probably just need to get something that works for correct input, not worry about handling incorrect input gracefully.
Is this actually how the code is written?
In d[count1]='/0'; I think you mean d[count1]='\0'; (already mentioned by Daniel Pryden).
There is also a semicolon missing at the end of memset(d,'\0',100)

Sort Strings by first letter [C]

I have a program which places structures in a linked list based on the 'name' they have stored in them.
To find their place in the list, i need to figure out if the name im inserting is earlier or later in the alphabet then those in the structures beside it.
The names are inside the structures, which i have access to.
I don't need a full comaparison if that is more work, even just the first letter is fine.
Thanks for the help!
It's not clear to me what your question is, but something like this would work:
if (node1->name[0] <= node2->name[0]) {
...
} else {
...
}
This will compare the first letter of the name in each of the nodes.
If you have two C strings, a and b, you can simply compare their first elements:
*a == *b
Where == can be any of the six relational operators.
Remember that with C strings, the char* points to the first character in the string.
strcmp() compares two C strings and will tell you what order they're in, or if they're the same. If you don't care about case, you can use strcasecmp(). These functions won't compare any more of the strings than necessary to determine what order to return.
strcmp man page
strcasecmp man page
You can simply iterate through the list and insert the new element in the correct place based on comparisons you do while passing each element. The simplest case sensitive version can be done just by comparing the numeric values of the letters (e.g. a[0] < b[0]), or you can convert both to a common case if you want to be case-insensitive (see ctype.h). Or you can compare the whole words with strcmp.

Resources