C : reversed array only prints when explicitly looped through - arrays

I am 'saving' the reverse of an array into a new array.
Example:
array A = abc
array B = cba
The below code is my solution. The new reversed array B does not print unless it is explicitly looped over. Both fprint %s and fprint %c on individual elements print white space. What is causing this?
Note: Function takes a number and converts to a string first.
int reverse(int x){
int len = int_length(x); //Functions works, gets the length
len++; //add room for \0
char *num = (char *)malloc(len * sizeof(char));
char *ans = (char *)malloc(len * sizeof(char));
snprintf(num, len, "%d", x); //Turn the numbers into a char array
printf("%s\n", num);
int i;
for(i = 0; i < len; i++) {
ans[i] = num[len-(i+1)];
}
for(i = 0; i < len; i++) {
printf("%c\n", ans[i]); //PRINTS FINE
}
printf("\n%c\n", num[0]);
printf("%c\n", ans[0]); //NOTHING PRINTS
printf("%s\n", ans); //NOTHING PRINTS
return 0;
}

len++; //add room for \0
char *num = (char *)malloc(len * sizeof(char));
char *ans = (char *)malloc(len * sizeof(char));
that's good to add 1 to the length, but then don't use that number as the actual string length
Without debugging it, my guess is the nul terminator winds up at the start of the reversed string, making it empty when printed as a string (but showing up okay when you're forcing all characters to be printed beyond the ill-placed nul terminator)
I would not change len, then explicitly add 1 when allocating:
char *num = malloc(len+1);
char *ans = malloc(len+1);
(and of course drop the usual redundancy: don't cast a pointer from malloc, don't multiply by sizeof(char) since it's always 1)

Related

sprintf to reverse an int and store as char

I"m trying to store int array as a str and display it but in the reverse order.
Its only while printing the str that i get junk.
What is wrong in my code?
int main() {
int a[] = { 1, 2, 3 }; // Output should be 321 (char)
int size = sizeof(a) / sizeof(int);
char str[size + 1];
int i;
for (size = size - 1; size >= 0; size--) {
sprintf(&str[size], "%d", a[size]);
//printf("%c\n", str[size]);
}
printf("%s\n", str); // I get garbage.
}
I modified your solution with several bug fixes. For starters, you can't assume that your integer array will only hold single digit values.
And that for loop as you have it:
for(size=size-1;size >= 0;size--)
Is very suspicious looking. (the index variable is the thing its based off?)
Simple solution
This is likely what you meant:
for(i = 0; i < size; i++) {
sprintf(&str[i],"%d", a[size-1-i]);
}
str[size] = '\0';
Or this:
str[size] = '\0';
for(i = size-1; i <= 0; i--) {
sprintf(&str[i],"%d", a[size-1-i]);
}
Better solution
I'm not sure what you are expecting to do if an integer within the a array is negative. So the - sign will just get inserted into str inplace.
The solution I have will first count how many chars are needed for each integer in a. Then it will allocate the str buffer with that length (+1 for null char).
Then we make use of the return value from sprintf to figure out where to concatenate onto. We could use strcat, but this is likely faster.
int main() {
int j = 0;
int a[] = { 1,2,3 }; // Output should be 321 (char)
int size = sizeof(a) / sizeof(int);
int length = 1; // +1 for final null char
// Count the size of characters needed for each integer
// Do a dummy sprintf and use its return value to figure out how many chars are needed
for (int i = 0; i < size; i++) {
char tmp[sizeof(int) * 5]; // sizeof(int)*5 is big enough to hold any integer including a negative value
length += sprintf(tmp, "%d", a[i]); // utilize the return value from sprintf and add it to the running length
}
char str[length];
str[0] = '\0'; // initially null terminate our string
// reverse print chars from a into str
for (int i = 0; i < size; i++) { // use i as index variable, not size
j += sprintf(str + j, "%d", a[size - 1 - i]);
}
printf("%s\n", str);
}
Alternative solution, closer to original posts, and clearly not trying to address the general problem (assume values are single digit):
int a[]={1,2,3}; // Output should be 321 (char)
int size = sizeof(a)/sizeof(int);
char str[size+1];
for(int i=0; i<size ; i++) {
str[size-1-i] = ‘0’ + a[i];
}
str[size] = 0;
printf("%s\n", str); // I get garbage.
}
Taking advantage of the assumed input value, converting each int to character representation at the reverse position.

Weird value at the end of a string

the function is called here
printf("copy %s\n", string_dupe(s1));
and the function is
char* string_dupe(char *s){
char* new_s;
new_s = malloc(8 * sizeof(s));
int i;
for (i = 0; i < size_of(s); i++){
new_s[i] = s[i];
}
s[i] = '\0';
return new_s;
}
So i've created the NULL byte or i at least think i have. But whenever i run this is keeps getting random values on the end of the input string. i put statements around it checking the ith value and it appears to be a null byte. i also check the next i + 1 element and it is never the same as the value that appears, can anyone help me out?
example input
s[] = "beetles"
ouput - beetles?
sizeof(s) will return the size of the pointer which is 4 or 8 byte. And sizeof(*s) will return size of char (because s is char*) which is 1 byte. To get the length of the string you have to iterate over it until you reach \0 or use strlen.
char* string_dupe(char *s){
unsigned int len = 0;
while (s[len] != '\0') ++len; // conpute length of string
char* new_s = (char*) malloc(len + 1); // one extra byte for '\0'
unsigned int i;
for (i = 0; i < len; ++i){
new_s[i] = s[i];
}
new_s[i] = '\0'; // Append '\0' to new_s not s
return new_s;
}
use strlen(s) to compute the length of the string.
you are suppose to terminate string pointed by new_s with '\0' not s.
char* string_dupe(char *s)
{
char* new_s;
size_t len = strlen(s);
new_s = malloc(len+1);
if (new_s != NULL)
strcpy(new_s,s);
return new_s;
}

array input wrong using strcpy

The code is supposed to take in as many string as the user wants to put in until they enter EOF. and it is doing that but after i try to ouput the code it comes out with these little half boxes instead of the string.
void sortString(char *s[], int count);
int main(){
int i;
char buff[BUFSIZ];
int count;
char** s = (char**)malloc(sizeof(char*));
//allows user to keep typing until EOF is reached.
printf("Here is the list of unsorted names: \n\n");
for (count = 0; fgets(buff, sizeof(buff), stdin); count++)
{
s[count] = malloc((sizeof(buff))*sizeof(char));//allocats memory at s[count].
strcpy(buff, s[count]);//adds the string in buff to s[count].
s = (char**) realloc(s, ((sizeof(s) + sizeof(buff)) * sizeof(char*)) + 1);//then reallocats memeory for s to take another string.
}
printf("\nCount is %d\n\n", count);
// Now sort string using sortString function
// Step 4: implement sortString function for the above-mentioned function declaration
for (i = 0; i < count; i++){
printf("%s \n",s[i]);
}
sortString(s, count);
printf("Here is the list of sorted names: \n\n");
for (i = 0; i < count; i++){
printf("%s",s[i]);
}
strcpy(buff, s[count]);//adds the string in buff to s[count].
No it doesn't. strcpy(dest, src), so it is copying s[count] (which is a buffer full of "random junk") to buff.

dynamically allocated char array only prints first character from each index

I'm trying to read from a file which has words in which are separated by spaces, the words are read within a loop. They are read correctly within the loop and they can be printed as so but as soon as the loop ends I am only able to print the first character of each element. Here is the code:
char **storeWords(char **words){
char* fileName = "words.txt";
FILE* fp = fopen(fileName, "r");
int i;
for (i = 0; i < 2; i++){
int j;
for (j = 0; j < 20; j++){
fscanf(fp, "%s", &words[i][j]);
printf("%s", &words[i][j]); //prints correctly
}
}
printf("%s", &words[0][0]); //prints first character of selected element
fclose(fp);
return **words;
}
int main(){
char **words = (char**)malloc(6 * sizeof(char*));
for (int i = 0; i < 6; i++){
words[i] = (char*)malloc(20 * sizeof(char));
}
storeWords(words);
system("pause");
return 0;
}
I don't understand why this happens, it would be appreciated if this could be explained. Thanks.
The problem is that you are allocating a 2D array of chars, not a 2D array of strings.
This is a pointer to a string, or a 1D array of chars:
char*
This is a pointer to a 1D array of strings, or a 2D array of chars:
char**
And this is a pointer to a 2D array of strings, or a 3D array of chars:
char***
You were trying to store a string to a char, and the only reason you didn't get a crash was because you allocated a [6][20] array but only iterated over 2x20 words, so there was room for overflow.
So, in your main function you need to allocate like this (note you don't need to cast the pointer returned from malloc):
char ***words = malloc(6 * sizeof(char**));
for (int i = 0; i < 6; i++){
words[i] = malloc(20 * sizeof(char*));
}
Change your function declaration to use the new type:
char ***storeWords(char ***words)
Then when you read in the words, use a temp char buffer and dynamically allocate enough space based on the word size:
for (j = 0; j < 20; j++){
char word[100]; // max word size of 100 chars
fscanf(fp, "%99s", word);
words[i][j] = malloc(strlen(word) + 1);
strcpy(words[i][j], word);
printf("%s", words[i][j]); //prints correctly
}
Note that when you print out a word you don't need to use the ampersand, because words[i][j] now contains a char* not a char:
printf("%s", words[0][0]);

Assign first character of a char array to another variable

I would like to grab a single character from a char array and move it into another character array. It is driving me crazy that i am having so much difficulties with something so simple.
My code is meant to reverse a string 2 values at a time. I have a string (ABCDEFGH) and i want to separate it into two strings (ACEG & BDFH). How would i go about doing this?
Currently, i have this:
char *hexrev(char str[]){
int i = 0;
char a[256];
char b[256];
int len = strlen(str);
for(i; i<len-1; i+=2)
{
printf("str[i] : %c\n", str[i]);
a[0] = str[i];
b[0] = str[i+1];
a[1] = '\0';
b[1] = '\0';
printf("A : %s\n", a);
printf("B : %s\n", b);
}
return str;
}
By changing sizeof(str) to strlen(str) and terminating a & b, I was able to get the code to work. Thank you!
You cannot use sizeof on an array inside a function. You must either use strlen() (once, preferrably) to compute the length, or pass it in as an extra argument.
Also you cannot legally print a and b as strings since you never ensure they're properly terminated.
Third, you only ever write to the first characters of a and b, so they will never grow longer than 1 character.
You should show a slightly more complete example, at least including the code that does the call to your function.
int i = 0, j = 0;
char a[256];
char b[256];
int len = strlen(str);
for(i; i<len-1; i+=2){
a[j] = str[i];
b[j++] = str[i+1];
}
a[j] = b[j] = '\0';
printf("A : %s\n", a);
printf("B : %s\n", b);
#include <stdio.h>
int main(void){
char str[] = "ABCDEFGHI";//In the case of odd-length
char a[256]={0};//letter of the index of odd numbered.(odd : 1 origin)
char b[256]={0};//for even
int i;
char *p[] = {a, b};
for(i = 0; str[i]; ++i){
*p[i & 1]++ = str[i];
}
printf("A : %s\n", a);//ACEGI
printf("B : %s\n", b);//BDFH
return 0;
}

Resources