Home > Enterprise >  Add strings to an array
Add strings to an array

Time:04-10

The problem: After the convert_tolower(words) function is completed I want to add a new word in the words array( if the words array has less than 5 words)..But I am getting either errors or unexpected results(e.g some weird characters being printed)...What i thought is shifting the elements of the words array and then work with pointers because I am dealing with strings.But I am having quite some trouble achieving that..Probably the problem is in lines 35-37

How I want the program to behave:

  1. Get 5 words(strings) at most from user input
  2. Take these strings and place them in an array words
  3. Convert the elements of the array to lowercase letters
  4. After the above,ask the user again to enter a new word and pick the position of that word.If the words array already has 5 words then the new word is not added.Else,the new word is added in the position the user chose.(The other words are not deleted,they are just 'shifted').

Also by words[1] I refer to the first word of the words array in its entirety

The code:

#include <stdio.h>
#include <string.h>

#define W 5
#define N 10

void convert_tolower(char matrix[W][N]);

int main() {
  int j = 0;
  int i = 0;
  int len = 0;
  char words[W][N] = {{}};
  char test[W][N];
  char endword[N] = "end";
  char newword[N];
  int position;
  while (scanf("%9s", test), strcmp(test, endword)) {
    strcpy(words[i  ], test);

    j  ;
    len  ;
    if (j == W) {
      break;
    }
  }

  convert_tolower(words);

  printf("Add a new word\n");
  scanf("%9s", newword);
  printf("\nPick the position\n");
  scanf("%d",position);
  if (len < W) {
    for (i = 0; i < W-1; i  ) {
      strcpy(words[i], words[i   1]); /*Shift the words */
      words[position] = newword;
    }
  }

  for (i = 0; i < W; i  ) {
    printf("%s", words[i]);
    printf("\n");
  }

  printf("End of program");
  return 0;
}

void convert_tolower(char matrix[W][N]) {
  int i;
  int j;
  for (i = 0; i < W; i  ) {
    for (j = 0; j < N; j  ) {
      matrix[i][j] = tolower(matrix[i][j]);
    }
  }
}

CodePudding user response:

This initialization

char words[W][N] = {{}};

is incorrect in C. If you want to zero initialize the array then just write for example

char words[W][N] = { 0 };

In the condition of the while loop

while (scanf("%9s", test), strcmp(test, endword)) {

there is used the comma operator. Moreover you are using incorrectly the two-dimensional array test instead of a one-dimensional array

It seems you mean

char test[N];

//...

while ( scanf("%9s", test) == 1 && strcmp(test, endword) != 0 ) {

And there are used redundantly too many variables like i, j and len.

The loop could be written simpler like

char test[N];

//...

for ( ; len < W && scanf("%9s", test) == 1 && strcmp(test, endword) != 0;   len ) 
{
    strcpy(words[len], test);
}

In this call

scanf("%d",position); 

there is a typo. You must to write

scanf("%d", &position); 

Also you should check whether the entered value of position is in the range [0, len].

For example

position = -1;

printf("\nPick the position\n");
scanf("%d", &position); 

if ( len < W && -1 < position && position <= len ) {

Also this for loop

for (i = 0; i < W-1; i  ) {
  strcpy(words[i], words[i   1]); /*Shift the words */
  words[position] = newword;
}

does not make a sense. And moreover this assignment statement

  words[position] = newword;

is invalid. Arrays do not have the assignment operator.

You need to move all strings starting from the specified position to the right. For example

for ( i = len; i != position; --i )
{
    strcpy( words[i], words[i-1] );
}

strcpy( words[position], newword );
  len;

And it seems the function convert_tolower should be called for the result array after inserting a new word. And moreover you need to pass the number of actual words in the array.

convert_tolower(words, len);

The nested loops within the function convert_tolower should look at least the following way

void convert_tolower(char matrix[][N], int n) {
  int i;
  int j;
  for (i = 0; i < n; i  ) {
    for (j = 0; matrix[i][j] != '\0'; j  ) {
      matrix[i][j] = tolower(( unsigned char )matrix[i][j]);
    }
  }
}

CodePudding user response:

With strcpy(words[i], words[i 1]) the type of word[i] and word[i 1] are *char[N] which are incompatible with the pointer char * and const char * expected. This was when word was declared as char *words[W][N]. The enclosing loop iterates i from 0 to W - 1 which means in the last iteration you deference words[W - 1 1] which is out of bound. Op has revised coe many times so it may no longer apply but that was the key issues initially.

Your main problem appears to with the words data structures and insert into words along with code organization so I wrote you a minimal implementation. Step 4 is not sufficiently specified. insert currently shift. It is not clear what should happen if you insert at position after empty slots, or if insert a position before empty slots and in particular if there are non-empty slots after said position.

#include <ctype.h>
#include <stdio.h>
#include <string.h>

#define W 5
#define N 10

void convert(size_t w, size_t n, char list[][n]) {
    for(size_t i = 0; i < w; i  ) {
        for(size_t j = 0; j < n; j  ) {
            list[i][j] = tolower(list[i][j]);
        }
    }
}

void insert(size_t w, size_t n, char list[][n], size_t pos, char *word) {
    // out out of bounds
    if(pos   1 > w) return;

    // last (i.e. w - 1) pos
    if(pos   1 == w) {
        strcpy(list[pos], word);
        return;
    }

    // 0 through w - 2 pos
    for(size_t i = w - 2; i >= pos; i--) {
        strcpy(list[i   1], list[i]);
        if(!i) break;
    }
    strcpy(list[pos], word);
}

void print(size_t w, size_t n, char list[][n]) {
    for (size_t i = 0; i < w; i  ) {
        printf("%d: %s\n", i, list[i]);
    }
}

int main() {
    char words[W][N] = { "a", "BB", "c" };
    convert(W, N, words);
    insert(W, N, words, 0, "start");
    insert(W, N, words, 2, "mid");
    insert(W, N, words, 4, "end");
    insert(W, N, words, 5, "error")
    print(W, N, words);
    return 0;
}

and the output (note: "c" was shifted out as we initially had 3 elements and added 3 new words with valid positions):

0: start
1: a
2: mid
3: bb
4: end
  • Related