0
#define WORDSIZE 64

char wordBuffer[64];

void flush(char* buffer, int buffersize);

typedef struct{
    char target[WORDSIZE];
    char swap[WORDSIZE];
}cypherEntry;

//stuff gets loaded in here through a function that's tested and working
typedef struct{
    cypherEntry* table;
    int size;
}cypher;

//some extra code that's working

/**
 * @brief Compares wordBuffer against the items in the cypher table.
 * 
 * @param cyphr the cypher table
 * @param index the index of the cypher table (return value)
 * @param target 0 if the word matches the target entry, 1 otherwise
 * @return int 0 if the wordBuffer is present in the cypher table, 1 otherwise
 */
int compareCypher(cypher* cyphr, int* index, int* target){
    for(int i=0;i<cyphr->size;i++){
            if(!cmpwrd(wordBuffer, cyphr->table[i].target)){
                if(cmpwrd(wordBuffer, cyphr->table[i].swap)){
                    *index = i;
                    *target = 1;
                    return 0;
                }
            }
            else{
                *index = i;
                *target = 0;
                return 0;
            }
        }
    return 1;
}

void cypherWord(char* cypher){
    char* word;
    strcpy(word, wordBuffer);
    flush(wordBuffer, WORDSIZE);
    int j, i=0;
    for(j=0;ispunct(word[j]);j++){
        wordBuffer[i] = word[j];
        i++;
    }
    for(int k = 0; k <strlen(cypher);k++){
        wordBuffer[i] = cypher[k];
        i++;
    }
    for(;j < strlen(word);j++){
        if(ispunct(word[j])){
            wordBuffer[i] = word[j];
            i++;
        }
    }
}

/**
 * @brief Cyphers a piece of text
 * 
 * @param cyphr the cypher table
 * @param text the text to be cyphered
 * @return char* pointer to the cyphered text
 */
char* cypherText(cypher* cyphr, char* text){
    char* cypheredText;
    strcpy(cypheredText, "\0");
    int lastIndex = 0, foundWord = 0;
    for(int i = 0; i <strlen(text); i++){
        printf("%d ", i);
        if(text[i] == ' ' || text[i] == '\n'){
            int j=0;
            for(; j<=i-lastIndex;j++)
                wordBuffer[j] = text[lastIndex+j];
            wordBuffer[j]='\0';
            lastIndex=i+1;
            foundWord=1;
        }
        if(foundWord){
            int index, target;
            if(!compareCypher(cyphr, &index, &target)){
                if(!target) cypherWord(cyphr->table[index].swap);
                else cypherWord(cyphr->table[index].target);
                //int where;
                //if(!hasPunct(&where)){
                    //if(!where) handlePrefix(cyphr, index, target);
                  //  else handleSuffix(cyphr, index, where, target);
                //}
                //else handleNoffix(cyphr, index, target);
            }
            printf("%s %d\n", wordBuffer, i);
            strcat(cypheredText, wordBuffer);
            foundWord=0;
        }
    }
    text = cypheredText;
    printf("%s\n", cypheredText);
    return cypheredText;
}

/**
 * @brief Flushes a buffer a buffer 
 * 
 * @param buffer pointer to the buffer to be flushed
 * @param buffersize the size of the buffer
 */
void flush(char* buffer, int buffersize){
    for(int i = 0; i <buffersize;i++)
        buffer[i]='\0';
}

I left out most of the code and only posted the problem part.

The point is making a program that forks, reads from STDIN, passes the text through a pipe to child, cyphers the text in the child according to the cypher stored in cypher.txt, then passes said cyphered text back to parent and prints it to STDOUT.

Instead of using strstr and strpbrk I decided to make my own string comparator, to handle cases like .word, .word. and such. I figured i was overcomplicating the process of cyphering words with punctuation and made the cypherWord function, which is more straightforward. The code was running well and is doing what it's supposed to when the commented portion (old implementation) is plugged in. However when i run it with the new implementation it goes smoothly for 6 words, then suddendly stops.

I left the debug print statements for ease of debug. The last one in the function, which contains the fully cyphered text, isn't even being printed. Here's the output:

0 1 2 3 4 Such  4
5 6 7 is  7
8 9 10 11 the  11
12 13 14 15 16 17 18 nature  18
19 20 21 of  21
22 23 24 25 26 27 28 .good. 28

Thanks in advance

  • 1
    This is going to go badly: `char* word; strcpy(word, wordBuffer);` – jarmod May 25 '22 at 01:07
  • that would result in a segfault then, no? – Pedro Barbeira May 25 '22 at 01:08
  • you were right. thanks! still would like to know why it's behaving the way it is tho – Pedro Barbeira May 25 '22 at 01:09
  • It would result in [undefined behavior](https://stackoverflow.com/questions/2397984/undefined-unspecified-and-implementation-defined-behavior). It could segfault, or it could download War and Peace from the internet and fax it to Johnny Depp's courthouse, or something else entirely. – jarmod May 25 '22 at 01:10
  • See: [Passing destination string as a pointer in strcpy](https://stackoverflow.com/q/68427119/2505965), and along the same lines, [sprintf() with automatic memory allocation?](https://stackoverflow.com/q/3774417/2505965) – Oka May 25 '22 at 01:20
  • 1
    I'd also recommend compiling with max warnings and even 'treat warnings as errors'. – jarmod May 25 '22 at 01:21

0 Answers0