array input wrong using strcpy - c

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.

Related

Function returning different values inside another function

My first function checks for the number of letters that a substring contains from its string.
int num_matches(char* word, char* letters) {
char scrabble[128];
strcpy(scrabble, letters);
int num = 0;
for (int i = 0; i < strlen(word); i++) {
if (strchr(letters, word[i]) == NULL) {
return -1;
}
for (int j = 0; j < strlen(letters); j++) {
if (word[i] == letters[j]) {
num++;
scrabble[j] = '\0';
break;
}
}
}
return num;
}
It returns 4 for "QWOP", "QWOP". However, inside the following function it is returning the same incorrect value for every function call, even when buff and letters print as "QWOP", "QWOP" from my debugging attempt.
void read_words(int num_count[128], char* (*word_idx)[128], int argc, char** argv) {
FILE* fp = fopen(argv[1], "r");
char* letters = argv[2];
int idx = 0;
char buff[128];
int result = 0;
while (fgets(buff, 128, fp) != NULL) {
printf("buff:%s letters:%s\n", buff, letters);
result = num_matches(buff, letters);
printf("result: %d\n", result);
num_count[idx] = result;
char* word = malloc(strlen(buff) + 1);
strcpy(word, buff);
(*word_idx)[idx] = word;
idx++;
result = 0;
}
fclose(fp);
}
buff:QWOP
letters:QWOP
result: -1
My txt file:
ABC
DEFG
QWOP
QWOP
QUOKKA
QUOLL
QUASH
QUANDONG
Since fgets stops at a newline and there are no spaces in my text file, I don't think there should be any problems with reading buff.
fgets reads the data with \n character at the end.
Your function will fail in this case. It is very easy to test:
int main(void)
{
printf("%d\n", num_matches("ABCD", "ABCD"));
printf("%d\n", num_matches("ABCD\n", "ABCD"));
}
Result:
4
-1
You need to remove \n from the buff.
Another problem is the second function. The parameter char* (*word_idx)[128] is a pointer to an array of 128 pointers to char. I do not think that is something you want.

C : reversed array only prints when explicitly looped through

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)

Copying strings of equal length to new string array

I have a dictionary of words stored in a 2D char array. I also have a scanned word stored in a structure. I'm trying to 'thin down' my main dictionary by copying words of length equal to the scanned word into a seperate 2D array. Then I want to print the new array out.
i.e if scanned word = hello, all words of the same length will be copied into the new array.
My code just prints the first word of the array infinitely
words.startword is the scanned word.
void get_equal_length (char equal_length_dictionary[MAX_WORDS][MAX_WORD_LENGTH], char dictionary[MAX_WORDS][MAX_WORD_LENGTH], Scanned_words words)
{
int i, word_count = 0;
for (i = 0; dictionary[i] != '\0'; i++)
{
if (strlen(*dictionary) == strlen(words.startword))
{
strcpy(*equal_length_dictionary, *dictionary);
word_count++;
printf("Word #%d: %s\n", word_count, *equal_length_dictionary);
}
}
printf("Equal length words: %d\n", word_count);
}
for (i = 0; dictionary[i] != '\0'; i++)
{
if (strlen(dictionary) == strlen(words.startword))
{
strcpy(*equal_length_dictionary, *dictionary);
should be:
for (i = 0; dictionary[i][0] != '\0'; i++)
{
if (strlen(dictionary[i]) == strlen(words.startword))
{
strcpy(equal_length_dictionary[i], dictionary[i]);
Also, to improve speed, better calculate strlen(words.startword) only once before the loop, instead of recalculating it inside the loop at each iteration. You should also not forget to terminate the new array with a null string.
The full code will be:
void get_equal_length(char equal_length_dictionary[MAX_WORDS][MAX_WORD_LENGTH], char dictionary[MAX_WORDS][MAX_WORD_LENGTH], Scanned_words words)
{
int i, word_count = 0, len = strlen(words.startword);
for (i = 0; dictionary[i][0] != '\0'; i++)
{
if (strlen(dictionary[i]) == len)
{
strcpy(equal_length_dictionary[i], dictionary[i]);
word_count++;
printf("Word #%d: %s\n", word_count, equal_length_dictionary[i]);
}
}
// now we will also terminate the new array with a null string
equal_length_dictionary[i][0] = '\0';
printf("Equal length words: %d\n", word_count);
}
This should work, although not tested. As Kevin mentioned in the comment, you need to use the index i in the loop. You also should use word_count as index:
void get_equal_length (char equal_length_dictionary[MAX_WORDS][MAX_WORD_LENGTH], char dictionary[MAX_WORDS][MAX_WORD_LENGTH], Scanned_words words)
{
int i, word_count = 0;
for (i = 0; i < MAX_WORDS; i++)
{
char* cur_word = dictionary[i];
if (!cur_word || !*cur_word)
break;
if (strlen(cur_word) == strlen(words.startword))
{
strcpy(equal_length_dictionary[word_count], cur_word);
word_count++;
printf("Word #%d: %s\n", word_count, equal_length_dictionary[word_count]);
}
}
printf("Equal length words: %d\n", word_count);
}

Insert element into dynamic char array in C programming

I was having some problem when trying to add element to dynamic char array in C programming. Here is the expected output:
How many characters do you want to input: 5
Input the string:datas
The string is: datas
Do you want to 1-insert or 2-remove or 3-quit?: 1
What is the character you want to insert: a
Resulting string: adata
I already did those user input part in the main function and here is the code in main where I take in the string input, size and pass them to insert():
printf("How many characters do you want to input: ");
scanf("%d", &n);
str = malloc(n + 1);
printf("Input the string class: ");
scanf("%s", str);
case '1':
printf("What is the character you want to insert: ");
scanf(" %c", &input);
insert(str, input, n);
break;
And the part where my insert():
void insert(char *str, char input, int n) {
int i;
size_t space = 1;
for (i = 0; i < n; i++) {
str[i] = (char)(input + i);
space++;
str = realloc(str, space);
if (i > 2) {
break;
}
}
for (i = 0; i < n; i++) {
printf("%c", str[i]);
}
}
However, when I tried to print out the string from insert(), let's say I entered 'a' to append to the first element of dynamic array with a size of 5, the result that I am getting is abcd=
I referenced from the stackoverflow thread and I not sure how to fix this. Thanks in advance.
Here is the code - with the contract that the caller does the free bit! The caller calls it with insert(&str, input, n)
void insert(char **str, char input, int n) {
char* temp = *str;
int i;
*str = realloc(*str, n + 2); /* realloc first */
if(!*str) /* realloc failed */
{
fputs("realloc failed", stderr);
free(temp); /* Free the previously malloc-ed memory */
exit(-1); /* Exit the program */
}
for (i = n; i >= 0; i--) {
(*str)[i + 1] = (*str)[i]; /* Move all characters up */
}
(*str)[0] = input; /* Insert the new character */
printf("%s", *str); /* Print the new string */
}
Sorry about the formatting. That is left to the reader. I have not checked the algorithm but this does not leak memory
You can use
void insert(char **str, char input, int n) {
char* temp = *str;
int i;
*str = realloc(*str, n + 2); /* realloc first */
if(!(*str)) /* realloc failed */
{
fputs("realloc failed", stderr);
free(temp); /* Free the previously malloc-ed memory */
exit(-1); /* Exit the program */
}
for (i = n; i >= 0; i--) {
(*str)[i + 1] = (*str)[i]; /* Move all characters up */
}
**str = input; /* Insert the new character */
printf("%s", *str); /* Print the new string */
}
And pass str by reference using
insert(&str, input, n); /* Note the '&' */

C: Garbage characters in Console output

I am learning about C pointers by creating various simple functions. I have just created a function to reverse a char array. It works, but after the output it also displays a bunch of garbage chars (see screenshot below).
Here's my code:
void reverseString();
int main()
{
reverseString();
system("PAUSE");
return 0;
}
void reverseString()
{
char string1[20], string2[20];
char *ptr1, *ptr2;
ptr1 = &string1[0];
ptr2 = &string2[0];
printf("Enter string: \n");
scanf("%s", string1);
int len1 = strlen(string1);
int i;
for (i = 0; i < len1; i++)
{
ptr2[i] = ptr1[len1 - i - 1];
}
printf("%s\n", string2);
}
How can I get rid of the garbage chars? Is there something wrong with my code or did I just nto account for something or what?
You forgot to nul-terminate the new string:
int i;
for (i = 0; i < len1; i++)
{
ptr2[i] = ptr1[len1 - i - 1];
}
// Add this
ptr2[i] = '\0';
When you print a char*, it will keep reading until it finds that nul character. But since you left it out, it kept going and going...

Resources