I want to store the words of a text in a two dimensional character array, where identical words are stored exactly once. The problem is that program seems to not store the last few words. I have included the whole program, because I can't figure out the problematic part. Here's my try:
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define N 20
#define M 110
int main() {
char text[M], c[N][N], word[N];
int i, j, k=0, l=0, d, v;
for(i=0; i<N; i ) {
for(j=0; j<N; j ) {
c[i][j]='\0';
}
}
for(i=0; i<M; i ) {
text[i]='\0';
}
for(i=0; i<N; i ) {
word[i]='\0';
}
for(i=0; i<M; i ) {
d=scanf("%c", &text[i]);
if(d==EOF) {
text[i]='\0';
break;
}
}
for(i=0; i<strlen(text); i ) {
if(isspace(text[i])==0) {
word[l]=tolower(text[i]);
l ;
}
if((i==strlen(text)-1)||((isspace(text[i])!=0)&&(isspace(text[i 1])==0))) {
for(v=0; v<i; v ) {
for(j=0; j<N; j ) {
if(word[j]!=c[v][j]) {
break;
}
}
if(j==N) {
l=0;
break;
}
}
if(v==i) {
for(j=0; j<l; j ) {
c[k][j]=word[j];
}
k ;
l=0;
}
}
}
printf("\n\n");
for(i=0; i<N; i ) {
for(j=0; j<N; j ) {
printf("%c", c[i][j]);
}
printf(" ");
}
return 0;
}
For some input not all words get printed (not stored?).
For example with input: a b c d e f g h i k l m n o p
and Ctrl D
the output is: a b c d e f g h i k
I noticed that if I increase N
and give the same input, the number of words printed also increases. Any help will be much appreciated.
EDIT:
if we replace
for(v=0; v<i; v )
for(j=0; j<N; j )
//...
if(j==N)
//...
if(v==i)
with
for(v=0; v<k; v )
for(j=0; j<l; j )
//...
if(j==l)
//...
if(v==k)
the program works properly.
CodePudding user response:
How to find the bug with a debugger
First of all, so that you don't have to enter a long line of input whenever you restart your program in the debugger, I suggest that you replace the code
for(i=0; i<M; i ) {
d=scanf("%c", &text[i]);
if(d==EOF) {
text[i]='\0';
break;
}
}
with:
strcpy( text, "a b c d e f g h i j k l m n o p" );
That way, the input that you specified in your question will be hard-coded into the program, and keyboard input will no longer be required.
If your run your program in a debugger, setting breakpoints in key places and running the program line by line afterwards, then you will notice that in the line
if(word[j]!=c[v][j]) {
the variable v
sometimes has the value 20
. This is accessing the array c
out of bounds, because valid indices are only 0
to 19
. This is causing undefined behavior, and causing your program to falsely believe that the word already exists in the array, so that it does not print it.
How to fix the bug
The bug described in the previous section is probably due to the line
for(v=0; v<i; v ) {
being wrong. The variable v
should be limited to N
, not i
. So you should change that line to the following:
for(v=0; v<N; v ) {
If you then also change the line
if(v==i) {
to
if(v==N) {
then the program has the intended output.
Other remarks
It is also worth noting that your sending nearly 400 null characters to the output stream. Your terminal/console seems to to be ignoring them instead of displaying them, but some terminals may behave differently. Therefore, you may want to change the lines
for(i=0; i<N; i ) {
for(j=0; j<N; j ) {
printf("%c", c[i][j]);
}
printf(" ");
}
to the following:
for(i=0; i<N; i ) {
printf("%s", c[i]);
printf(" ");
}
That way, the null characters will not be sent to the output stream. However, if you do this, you can only store 19 characters instead of 20 characters in every string, because one extra byte is now required for the terminating null character. You may want to change your code to enforce this limit.