I am working on a portion of my code that is suppose to output the error message correctly.
Please see below screenshot, I am using on bash
./myProgram < input3a.in | diff -a -y output3a.out -
Left hand side is what I want to get to.
For some reason an extra "|" is printed before the char array 'line' is printed. I suspected that maybe the char array 'line' is not null terminated. but it is initialize by cin.getline(); which should null terminate the char array.
Here i try to print the 'line' array in my main procedure, and it left the | sign on the line before it.
my question is. why does std::cout display this behaviour?
Thanks
EDIT,
Below is my code in question. Thanks for taking a look again.
#include "char_stack.h"
#include <iostream>
void printErrorLine(int errorSpot, int c_count, char line[]){
//Print the first line of error message char by char, at the
//same time replace char with \t or space
for(int x = 0; x <= errorSpot; x++){
std::cout << line[x];
if(line[x] != '\t'){
line[x] = ' ';
}
}
std::cout << std::endl;
//Print out the second line, if the first line does not have a
//errorSpot, then dont print it
if(errorSpot != c_count){
std::cout << line << std::endl;
}
}
char findCounterPart(char bracket){
//pass.
}
int main(int argc, char * argv[]){
char line[250]; // 250 because spec sheet detailed max 250 char per line.
char c;
int l_count = 0; // number of lines already read
int c_count; // character count in a line
char_stack S;
bool isError;
while(!std::cin.peek() == std::cin.eof()){
std::cin.getline(line, 250);
c_count = std::cin.gcount();
l_count +=1;
//std::cout<< c_count << std::endl << std::endl;
//loop through the line
for(int x = 0; x < c_count; x++){
c = line[x];
//std::cout << c << " stack size is " << S.size() << std::endl;
if (c == '(' ||
c == '{' ||
c == '['){
S.push(c);
}
else if(c == ')' ||
c == '}' ||
c == ']'){
if(S.empty()){
std::cout << "Error on line " << l_count << ": Too many " << c << std::endl;
isError = true;
}
else{
char l = S.pop();
if(l != findCounterPart(c)){
std::cout << "Error on line " << l_count << ": Read " << c <<
", expected " << findCounterPart(l) << std::endl;
isError = true;
}
}
}
if (isError){
printErrorLine(x, c_count ,line);
return 0;
}
}
}
if (!S.empty()){
c = S.pop();
std::cout << "Error on line " << l_count << ": Too many " << c << std::endl;
printErrorLine(c_count, c_count , line);
}
else{
std::cout <<"No Errors Found" << std::endl;
}
return 0;
}
Learning to be a software engineer is about breaking problems down into manageable chunks, and here we have a couple of doosies. Lets rephrase your question slightly:
I am getting unexpected characters displayed when diff the output of my program against a file containing output of a previous run. Currently I think this is because of some weird behavior of std::cout.
Well, that might be a reasonable assumption, we can't see your code so we can't know if you're doing anything peculiar.
But it would have to be: std::cout is used, well, all over the place. It just doesn't have this behavior unless your code is deliberately writing a | somewhere.
There are a number of steps we could take to resolve this:
Run the program a 3rd time in the debugger and step through until you have some ideas where the '|' is appearing,
Run the program a 3rd time to the console and observe the output,
View the output using a command like cat, less or more, instead of diff
3 is perhaps the most sensible place to start, since the file is already right there and after that #2 will give us a mk1eyeball check.
What we find is: the | does not appear in the file or the output. It's not coming from your program.
Lets create a couple of .txt files and diff them:
osmith#WOTSIT MINGW64 ~
$ echo -e 'First line\nSecond line' >test1.txt
osmith#WOTSIT MINGW64 ~
$ echo -e 'First line\nFile two line 2' >test2.txt
osmith#WOTSIT MINGW64 ~
$ diff -a -y test1.txt test2.txt
First line First line
Second line | File two line 2
When using the -y switch, between the two columns of output, diff has a line of special characters to indicate lines that changed, were inserted or deleted.
Related
(I don't have much english vocabulary, so sry for this weird try of english)
Hi guys! I'm new at C++ and I need to know how to create a filter code that help me at only accept int-eger numbers. I need that this code use only the 'iostream' library. This is because my teacher don't let us use another kind of library (we are new at C++ coding).
Here I put an example of what I have at this moment:
# include <iostream>
# include <limits> //I should't use this library
using namespace std;
int main() {
int value = 0;
cout << "Enter an integer value: ";
while(!(cin >> value)) {
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << endl <<"Value must be an integer"<< endl << endl; //This line needs <limits>
cout << "Enter another integer value: " ;
}
}
But this code have some inconvenients:
I'm using "#include 'limits'" library and I shouldn't use it
If you enter "1asd" it takes the "1" value, give it like if its correct and it isn't true
Do you guys have any solution for this situation? Thanks in advance for your time.
You just have to check if the bytes that the user entered are numerals like below. If all the bytes of the entered string are numerals (ie between characters 0 and 9), then the entire string is an integer. Except first byte of the string can be a '+', '-', a space/tab or just the first numeral in the number. (Thanks Zett42).
std::cout << "Enter an integer value: ";
std::string res1;
std::cin >> res1;
std::string::iterator it;
for ( it = res1.begin() ; it < res1.end(); it++)
{ std::cout << "checking " << *it << ' ';
if (!( '0' <= *it && *it <= '9' )) {
std::cout << "this is a numeral\n";
} else {
std::cout << "you entered: " << *it << " -- this is *not* a numeral\n";
}
}
my assignment asks me to open a file, but if it doesn't open you are given 3 tries, but when I input the correct file on my second and third try it still give me the error I wrote 'ERROR: File " << input_filename << " could not be opened for input"' and goes to my else statement
char input_filename[90];
ifstream input;
cout << "Type the name of the input file which will hold the simulation results : " << endl;
cin>> input_filename;
input.open(input_filename);
if (input.fail())//if the file doesn't open it will go to the do while loop error message
{
int i = 0;
int h = 0;
do
{
cout << "ERROR: File " << input_filename << " could not be opened for input" << endl;
cin >> input_filename;// allows user to reinput filename
input.open(input_filename);//opens file
if ( !input.fail())
{
cout << "if statement" << endl;
h++;// if h doesn't equal 1 it goes out of the loop
}
else
{
cout << "else statement" << endl;
i++;//post-decrement allows for 2 more tries to input file
}
if (i >= 2)
{
cout << "ERROR: You exceeded maximum number of tries allowed" << endl;
cout << "while entering the input file name" << endl;
return 1;// return 1 represents the error of the input not opening after the 3rd time of inputing
}
} while (i < 2 && h != 0);// do while because it need to be a post condition for two varibles
}
If you reach line 106, it implies your file input succeeded. At that line you should NOT increment h. In fact you should leave h at zero if you want to break out of the loop (Assuming the file input worked).
I have two pairs of files. The source files are identical copies apart from the path to the identical text files they interrogate.
One pair runs on Linux Cinnamon 18.x the other on Raspbian Stretch. Each pair is compiled on its own platform.
std::string sTemp = ImportDS18B20("testy.txt");
if (sTemp.find("YES") != std::string::npos) {
size_t p = sTemp.find("t= ");
if (p != std::string::npos) {
p += 3;
sFloor = sTemp.substr(p);
uint uTemp = sFloor.length();
std::cout << uTemp << " |" << sFloor << "| " << std::endl;
}
break;
}
The code produces 5 |19555| on Raspbian and 6 |19555\n| on Cinnamon. (\n is of course just to represent a CR on this site.)
I assume this is a C++ compiler issue. Is that correct? How do I make the code portable?
I suspect that your issue is with the ImportDS18B20() function rather than the code you've posted or the compiler. To verify that the files are identical, check the length and md5sum.
I would strip trailing \r (and \n to make it cross-platform)
sFloor = sTemp.substr(p);
while (sTemp.back() == '\r' || sTemp.back() == '\n')
sTemp.pop_back();
uint uTemp = sFloor.length();
Mike
I'm currently confused on while loops, specifically why the loop still runs everything else in the loop specifically after the sentinel value is reached...
here's the example of my code below:
while (quit != -1) {
cout<<"Options: a)ir; w)ater; s)teel; q)uit \n";
char option=' ';
cin>>option;
option = toupper(option);
while( option != 'A' && option != 'W' && option != 'S' && option != 'Q'){
cin.clear();
cout<<"INVALID INPUT!! \n";
cin>>option;
option = toupper(option);
}
switch(option){
case 'Q':
cout<<"You Have Quit!";
quit = -1;
break;
}
cout<<"Please input the distance: \n";
double distance=0;
cin>>distance;
while(distance < 0){
cin.clear();
cout<<"INVALID INPUT \n";
cin>>distance;
}
switch(option){
case 'A':
seconds = distance/speed_a;
cout<< "Time travled: " << setprecision(2) << fixed << seconds << "\n";
break;
case 'W':
seconds = distance/speed_w;
cout<< "Time travled: " << setprecision(2) << fixed << seconds << "\n";
break;
case 'S':
seconds = distance/speed_s;
cout<< "Time travled: " << setprecision(2) << fixed << seconds << "\n";
break;
}
}
basically when the user enters the 'q' character it runs the quit switch statement... it does quit the loop but it still asks for the distance traveled before ending the loop..
output is shown below:
Options: a)ir; w)ater; s)teel; q)uit
q
You Have Quit!
Please input the distance:
0
--------------------------------
Process exited after 2.944 seconds with return value 0
Press any key to continue . . .
is there any way to edit the code so it immediately quits the loop or is this just the way all loops are pre-programmed?
any advice would be appreciated
The break statement Inside a switch case only exits the switch block, not the outer while loop. Your code continues to run until the next evaluation of the while loop condition.
I have a program that is supposed to take in a paragraph like
Testing#the hash#tag
#program!#when #beginning? a line
or #also a #comma,
and output something like
#the
#tag
#program
#when
#beginning
#also
#comma,
I feel like the logic makes sense, but obviously not because the program never seems to get into the line of input. The problem is almost definitely in the last source file below.
Here is the main source program
#include "HashTagger.h"
#include <string>
#include <iostream>
using namespace hw02;
using namespace std;
int main() {
// Construct an object for extracting the
// hashtags.
HashTagger hashTagger;
// Read the standard input and extract the
// hashtags.
while (true) {
// Read one line from the standard input.
string line;
getline(cin, line);
if (!cin) {
break;
}
// Get all of the hashtags on the line.
hashTagger.getTags(line);
}
// Print the hashtags.
hashTagger.printTags();
// Return the status.
return 0;
}
my header file
#ifndef HASHTAGGER_H
#define HASHTAGGER_H
#include <string>
namespace hw02 {
class HashTagger {
public:
void getTags(std::string line);
void printTags();
private:
std::string hashtags_;
};
}
#endif
and a source file
the test in the source file seems to show that the program only gets to the second line and then stops before grabbing the last 2 hashtags
#include "HashTagger.h"
#include <iostream>
using namespace std;
using namespace hw02;
void HashTagger::getTags(string line) {
// Loop over all characters in a line that can begin a hashtag
int b = 0;
string hashtags_ = "";
for (unsigned int j = 0; j < line.length(); ++j) {
char c = line.at(j);
// if "#" is found assign beginning of capture to b
if (c == '#') {
b = j;
// if the beginning is less than the end space, newline, ".", "?", or "!" found, add substring of the hashtag to hashtags_
}
if (b < j && (c == ' ' || c == '\n' || c == '.' || c == '?' || c == '!' )) {
hashtags_ = hashtags_ + "\n" + line.substr(b, j - b + 1);
b = 0;
//Test// cout << b << "/" << j << "/" << c << "/" << hashtags_ << "/" << endl;
}
}
}
void HashTagger::printTags() {
// print out hashtags_ to the console
cout << hashtags_ << endl;
}
You are redeclaring hashtags_ inside your getTags function. Therefore, all string modifications operate on a local variable instead of the class member variable.
Change the line
string hashtags_ = "";
to
hashtags_ = "";
in order to avoid the redeclaration and operate on the class member variable used for the output later on.
Also, make sure that your input is terminated with two newline characters (\n\n), to avoid breaking out of the main loop too early, or move your check and break statement after the getTags call:
while (true) {
// Read one line from the standard input.
string line;
getline(cin, line);
// Get all of the hashtags on the line.
hashTagger.getTags(line);
if (!cin) {
break;
}
}