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:
- Get 5 words(strings) at most from user input
- Take these strings and place them in an array words
- Convert the elements of the array to lowercase letters
- 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