Ryan Fisher
Ryan Fisher

Reputation: 35

C...string splitting issue

I am having issues with my firstCheck() function. I will explain directly below with my current code. I have written this program using all my knowledge of C++.

The firstCheck() function is not working like it should. In readFile() function I have successfully split the text from a given file into an array line by line. Then firstCheck() should take that array "myString" and read the first string up until a " " occurs (basically the first word/character/etc.) so that I can evaluate it.

I'm pretty sure my issue is this part. The program seems to stop and wait for input I would assume because of "stdin" What is a better way to implement this snippet?

while(strcmp( fgets( item.myString, sizeof item.myString, stdin ), " " ) != 0 )
{ myWord[s] = strdup(item.myLines[s]); }

Should I use scanf() instead? I was told using gets() is bad practice, so i used fgets() instead

Assem.c

#include "assem.h"

int readFile(FILE *file, struct assem *item) 
{
    size_t i =0;
    item->counter = 0;  //this is sort of the constructor, if you will. 
    size_t maxLines = sizeof item->myLines / sizeof *item->myLines;  //breaks down text file into line by line 
    while(i < maxLines && fgets(item->myString, sizeof item->myString, file))  //and stores them into "myLines array"
    {
        item->myLines[i] = strdup(item->myString);
        i++;
        item->counter++;
    }   

    return 0;
}

void printFile(struct assem item)  //just printing things..prints it with a new line in front
{
    printf("\n");
    for(int s = 0; s < item.counter; s++)
    {
        printf("%s\n", item.myLines[s]);
    }
    printf("\n");
}

int firstCheck(struct assem item)               
{
    char *myWord [7] = {NULL};

    for(int s = 0; s < item.counter; s++)   
    {
        while(strcmp( fgets( item.myString, sizeof item.myString, stdin ), " " ) != 0 )         
        {
            myWord[s] = strdup(item.myLines[s]);
        }           
    }

    for(int s = 0; s < item.counter; s++)
    {
        printf("%s\n", myWord[s]);
    }

    return 0;       
}

"assem.h"

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

struct assem
{
    char myString[101];  //buffer
    char *myLines[20];  //this will store the lines from a text file..up to 20 lines
    int counter;  //counter for number of lines
    //printing stuff...prints file directly from whats STORED IN THE ARRAY
};

int readFile(FILE *FileToBeRead, struct assem *item);  //takes in the file that needs to be read and splits it into lines
int firstCheck(struct assem item);
void printFile(struct assem item);

"main.c"

#include "Assem.c"

int main()
{
    struct assem test;
    FILE *mips;
    mips = fopen("/home/rpf0024/cse2610/Program1/mips.asm", "r");
    readFile(mips, &test);
    printFile(test);
    firstCheck(test);
    fclose(mips);
    return 0;
}

Upvotes: 0

Views: 64

Answers (1)

Weather Vane
Weather Vane

Reputation: 34575

Answering "What is a better way to implement this snippet?" and not looking at the other code:

while(strcmp( fgets( item.myString, sizeof item.myString, stdin ), " " ) != 0 )

This will cause strcmp() to segfault at the end of file, because fget() will return NULL.

Also be aware that fgets() will keep any newline at the end of the input. So comparing the input with " " will never match (except if the last line of the file has no newline).

It is better like this

while (NULL != fgets(item.myString, sizeof item.myString, stdin)) {
    if (strcmp(item.myString, " \n"  != 0) {
       ...
    }
}

But I am not sure even that will work for you, since you probably want to find a space within a string, not as a whole file line. In this case, you should research strtok().

char *tok;
while (NULL != fgets(item.myString, sizeof item.myString, stdin)) {

    tok = strtok(item.myString, " \t\r\n");
    while (tok) {
        printf("%s\n", tok);
        tok = strtok(NULL, " \t\r\n");
    }

}

this will split your string into sections delimited by space(s) or other whitespace. But note that item.myString will be fragmented in the process, by the tokenising.

Upvotes: 1

Related Questions