noobcoder
noobcoder

Reputation: 343

Garbled string output

I'm currently working on an assignment which asks me to censor words of argv and input redirection.

My problem is obvious in my output which can be found below. I have a lot of tracing print statements which may or may not help you point out my issue.

My intention is:

  1. Get file.txt
  2. Copy contents of file.txt into buffer[x][y], where [x] is a string of word and [y] is a char of [x].
  3. Compare argv[] arguments to buffer[][].
  4. Create newstr[size2]. For every argv[] arguement found in buffer[][], replace it with replace[9] = "CENSORED".
  5. Print the string of newstr[0 to (size2-1)].

Here is my code:

// censored.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#define SIZE 128

int main ( int argc, char* argv[])
{
    int i = 0;
    int j = 0;
    int k = 0;
    char buffer[SIZE][SIZE];
    char x;
    int count = 0;
    int size1 = sizeof(buffer);
    int size2 = 0;
    char replace[9] = "CENSORED";
    int buffersize=0;
    printf("tracing: size1: %d.\n", size1);
    printf("tracing: argc: %d.\n", argc);
    while((fscanf(stdin, "%c", &x)!=EOF))
    {
        if(isalpha(x))
        {
            buffer[i][j]=x;
            printf("tracing: buffer[%d][%d]: %c\n", i,j, buffer[i][j]);
            j++;
        }
        else if(isspace(x)) // if whitespace
        {
            j = 0;
            i++;
            buffer[i][j]=x;//this should be buffer[i][j]
            printf("tracing: buffer[%d][%d]: %c\n", i,j, buffer[i][j]);
            j = 0;
            i++;
        }
        else if(ispunct(x)) // if x is a punctuation
        {
            j = 0;
            i++;
            buffer[i][j]=x;//this should be buffer[i][j]
            printf("tracing: buffer[%d][%d]: %c\n", i,j, buffer[i][j]);
        }
        else if(iscntrl(x)) // if control key (\n, \r etc...)
        {
            j = 0;
            i++;
            buffer[i][j]=x;//this should be buffer[i][j]
            printf("tracing: buffer[%d][%d]: %c", i,j, buffer[i][j]);
            j = 0;
            i++;
        }
        else if(isdigit(x))
        {
            buffer[i][j]=x;//this should be buffer[i][j]
            printf("tracing: buffer[%d][%d]: %c\n", i,j, buffer[i][j]);
            j++;
        }
        else
        {
            break;
        }
    }
    size2 = i;
    printf("tracing: buffer[8][0]:%s\n",buffer[8]);
    char newstr[size2][SIZE];
    i = 0;
    j = 0;
//  tracing:
    printf("tracing: line 72\n");
    printf("tracing: size2: %d.\n", size2);
    while(i < size2) //print buffer[]
    {
        printf("%s", buffer[i]);
        i++;
    }

    printf("tracing: line 80\n");
    for(k=1; k < argc; k++)
    {
        printf("%s\n", argv[k]);
    }
//  end tracing
    i = 0; //reinitialize i
    j = 0; //reinitialize j
//  creating newstr[SIZE] and censoring words
    printf("tracing: line 89\n");
    for(i = 0; i < size2; i++)
    {
        for(j=1; j < argc; j++)
        {
            if(strcmp(buffer[i], argv[j])==0)
            {
                strcpy(newstr[i], &replace[0]);
                printf("tracing: replaced at [%d]\n", i);
                break;
            }
            else
            {
                strcpy(newstr[i], buffer[i]);
                printf("tracing: copied at [%d]\n", i);
            }
        }
    }
    i = 0; //reinitialize i
    while(i < size2)
    {
        printf("%s", newstr[i]);
        i++;
    }
    return 0;
}

Assuming I have input redirection file named file.txt and its contents:

Said Hamlet to Ophelia,
I'll draw a sketch of thee,
What kind of pencil shall I use?
2B or not 2B?

my input is:

./censored Ophelia thee 2B < file.txt

this is the weird output I got:

Said Hamlet to CENSORED, Ill draw a sketch ???)ofoQ? ?"h?CENSORED,2oQ?
What? /oQ?kind? of 6oQ?pencil +oQ?shall ?"h?I-oQ? ???)use? ???2BoQ?
7oQoroQ Qnot 1oQ?CENSORED?4oQ?

Any help is appreciated, I know my code is messy, this is my first semester learning C.

Upvotes: 1

Views: 1141

Answers (1)

Kotshi
Kotshi

Reputation: 338

I have good and bad news, the bad one is: I found a few errors and mistake. The good one is: all of these are common for a beginner!

First one: The strings in buffer[] aren't terminated with a '\0' which is the end of string indicator. This is the one cause of your problem. And here are the other ones:

  • char buffer[SIZE][SIZE]; Here you are considering that number of words and word's length can't be longer that 128 which will cause Segmentation Fault whenever this condition is wrong. I suggest you learn about dynamic allocation (malloc()).
  • for(j=1; j < argc; j++) If argc == 1, you won't enter this loop which would result in newstr being empty. Usually we end arrays with a NULL pointer and then check for every string of the array being non-null while reading the array so that we won't try to use undefined content.
  • As you pointed at, your code is quite messy, next time, try separating your code in functions and not coding in main().
  • Try reducing this, the fewer lines your write, the easier your code is to read and debug:

j = 0; i++; buffer[i][j]=x;//this should be buffer[i][j] printf("tracing: buffer[%d][%d]: %c\n", i,j, buffer[i][j]); j = 0; i++;

  • This advice isn't really relevant for that kind of program designed to read a lot of data but remember: try to avoid storing data whenever you can.

I think this is enough for now, I wish you good luck and to apologize for my poor English.

Upvotes: 2

Related Questions