ddog ddog - 1 month ago 8
Linux Question

Read input until a specific string is found C++

I'm currently using this code to take in standard input and place it in a string. then tokenize using the delimeter #

std::string input;
std::getline(std::cin,input, '\0');
std::string delimiter = "#";
StringTokenizer strtok(input,delimiter);

This makes getline read until null character is found(I think) and pass the entire string into input.This works fine in windows when I run the cmd and write this :

myprogram.exe 0 <testme.txt

I get the output I am expecting.The problem I am having is when I try to run a similar command in linux terminal(a.out is my program)

./a.out < testme.txt

It will not stop looking for keyboard input until I push ctrl-z. This is also the case when I run in my IDE Code::blocks where the program is written. Both Code::blocks and linux compile with g++ with no errors or warnings. I think my issue lies with the waiting for a null character. The reason for using the null character is because my input is on multiple lines and when I just used getline(std::cin,input) only the first line was read.

Example testme.txt

A B C D E F #
A -> Bab #
B -> C #

Sample of what I'm doing with my code

std::string data;
std::getline(std::cin,data, '\0');
std::string delimiter = "#";
StringTokenizer strtok(data,delimiter);
// places first token in tk1
std::string t1 = strtok.nextToken();
std::string tk1(t1);
// places next token in tk2
std::string t2 = strtok.nextToken();
std::string tk2(t2);
if(checkstring(tk2,"a") > 0) // this function checks the amount of "a"s in the token. I only care if there is at least 1 "a" so that is what the if statements are for.
a = a + 1;
// do this if statement for every letter
// example: token = A -> abbbababababa then will print out a = 1 and b = 1

If put through my program the testme.txt should make my program output this:

a= 1
b= 1


Each of my testme.txt files ends with the two characters ##. Is there a way that I can stop reading input when this string(?) is reached instead of waiting for the null character?

//do stuff
if (yourString == "##")
}while(yourString != NULL);

Sometimes its easier than it seems

All your '#' are useless, if you delete them:

std::vector<std::string> tokens; // Storing all tokens
std::string line;
while (std::getline(file, line))

for (std::string s : tokens) //Gets all tokens one by one
    for (char c : s)// Gets all char in each token
        if (islower(c))// Checks if thats a lowercase letter
            std::cout << c << std::endl;

If you want to keep the '#':

while (std::getline(file, line))
    if (!line.find("#"));

If you're using std::cin instead of a file:

std::string input, line;
std::cin >> input;
std::stringstream sinput(input);

while (std::getline(sinput, line, '#'))