C++ 11, Reading characters from a stringstream returns last character twice - stringstream

So I'm reading from a stringstream character by character because I want to copy its content into another string in a specific format, the problem is that for some reason I get the last character of the stream to be copied twice. Here's the code
string infoTabella;
while(ss >> noskipws >> c){
if(c==44||c==40||c==41) {
infoTabella += ' ';
infoTabella += c;
infoTabella += ' ';
}else{
infoTabella += c;
}
}
shouldn't the while condition be set to false when I reach the end of the stream?
(sorry for bad English, not my first language)

Related

Write a lex program that detects and counts the pattern that starts with an uppercase letter, ends with a lowercase letter

I understood the problem and written the below code. My code works and it prints the number of detected valid and invalid patterns when I quit the program with ctrl+z.
Here is my code:
%{
int valid = 0;
int invalid = 0;
%}
%%
([A-Z][a-zA-Z0-9]*[a-z])* {valid++;}
[a-zA-Z0-9]* {invalid++;}
%%
int yywrap(){}
int main(int argc, char **argv[])
{
printf("\n Enter inputs: \n\n");
yylex();
printf("\n\n\tNumber of VALID patterns = %d\n", valid);
printf("\tNumber of invalid patterns = %d\n\n", invalid);
return 0;
}
But I want something like this:
It should print the detected patterns, number of valid patterns and the number of invalid patterns whenever I input a new line.
There should be an EXIT command.
To achieve your goal, you should modify your code like this:
/*** Definition Section ***/
%{
int valid = 0;
int invalid = 0;
%}
/*** Rules Section ***/
%%
([A-Z][a-zA-Z0-9]*[a-z])* {printf("\n\tPattern Detected: %s ", yytext); valid++;}
[a-zA-Z0-9]* {invalid++;}
"\n" {
printf("\n\n\tNumber of VALID patterns = %d\n", valid);
printf("\tNumber of invalid patterns = %d\n\n", invalid);
valid = 0;
invalid = 0;
}
EXIT__ return 0;
%%
/*** User code section***/
int yywrap(){}
int main(int argc, char **argv[])
{
printf("\n Enter inputs: \n\n");
yylex();
return 0;
}
Here main change comes in the rule section.
Rule-1: ([A-Z][a-zA-Z0-9]*[a-z])* It detect and count valid patterns that starts with an uppercase letter, ends with a lowercase letter. In action, it prints the detected patterns and does the counting job too. Here yytext contains the text in the buffer, for this rule, it's the detected pattern.
Rule-2: [a-zA-Z0-9]* Keep a track of invalid patterns. It will help to prevent returning unmatched patterns.
Rule-3: "\n" It detects when you input a new line. In action, it prints the detected patterns, the number of valid patterns, and the number of invalid patterns whenever I input a new line. Also, reset the variables for counting to zero for the next line of input.
Rule-4: EXIT__ whenever you will input this exact command, the program will exit.
You can avoid printing the numbers of valid and invalid patterns inside the main function in the user code section.
But if you want to print the numbers of detected valid and invalid patterns at the end too, then this program will require a few modifications.

How can I loop thorough a record one character at a time?

How can I loop thorough a record one character at a time? I want to interrogate records in a ASCII file one character at a time looking for and replacing non-printable characters. I tried using the Loop Condition with no luck. Thanks in advance for any help.
Yes, this is possible in a DataStage Transformer.
The "Loop Condition" creates a new output row per iteration. It operates on each row it receives. You might want to add a constraint to your output link which is only true when your loop iterations are finished (for that row).
A little pseudo-code to replace every 'ä' with a '?' by looping through char-by-char:
// Input Link "DSLink2"
// provides a column named "text"
// Stage Variables:
NVarCHar(20) svLine := DSLink2.text
NChar(1) svReplacementChar := "?"
// Loop Variables:
NChar(1) lvCharToTest
Bit lvCharOK := 0
NVarCHar(20) lvNewLine := ''
Integer i := 0
// Loop Condition:
loop while (i < Len(svLine)) {
i = i + 1
lvCharToTest := svLine[i,1]
// replace by proper test condition or function according to your needs:
lvCharOK := lvCharToTest = 'ä'
if (lvCharOK) {
lvNewLine = lvNewLine + lvCharToTest
}
else {
lvNewLine = lvNewLine + svReplacementChar
}
}
// DSLink4_output:
If (i = Len(svLine)) {
DSLInk4_output.text := lvNewLine
}
Screenshot of a Transformer Stage showing this example

Shifting a string in matlab

Ok so I have retrieved this string from the text file now I am supposed to shift it by a specified amount. so for example, if the string I retrieved was
To be, or not to be
That is the question
and the shift number was 5 then the output should be
stionTo be, or not
to beThat is the que
I was going to use circshift but the given string wouldn't of a matching dimesions. Also the string i would retrieve would be from .txt file.
So here is the code i used
S = sprintf('To be, or not to be\nThat is the question')
circshift(S,5,2)
but the output is
stionTo be, or not to be
That is the que
but i need
stionTo be, or not
to beThat is the que
By storing the locations of the new lines, removing the new lines and adding them back in later we can achieve this. This code does rely on the insertAfter function which is only available in MATLAB 2016b and later.
S = sprintf('To be, or not to be\nThat is the \n question');
newline = regexp(S,'\n');
S(newline) = '';
S = circshift(S,5,2);
for ii = 1:numel(newline)
S = insertAfter(S,newline(ii)-numel(newline)+ii,'\n');
end
S = sprintf(S);
You can do this by performing a circular shift on the indices of the non-newline characters. (The code below actually skips all control characters with ASCII code < 32.)
function T = strshift(S, k)
T = S;
c = find(S >= ' '); % shift only printable characters (ascii code >= 32)
T(c) = T(circshift(c, k, 2));
end
Sample run:
>> S = sprintf('To be, or not to be\nThat is the question')
S = To be, or not to be
That is the question
>> r = strshift(S, 5)
r = stionTo be, or not
to beThat is the que
If you want to skip only the newline characters, just change to
c = find(S != 10);

delimiting by a char but not deleting it

I have a text file that looks like this:
(a (bee (cold down)))
if I load it using
c=textscan(fid,'%s');
I get this:
'(a'
'(bee'
'(cold'
'down)))'
What I would like to get is:
'('
'a'
'('
'bee'
'('
'cold'
'down'
')'
')'
')'
I know I can delimit with '(' and ')' by specifying 'Delimiter' in textscan, but then I will loose this character, which I want to keep.
Thank you in Advance.
The %s specifier indicates that you want Strings, what you want is individual chars. Use %c instead .
c=textscan(fid,'%c');
Update if you want too keep your words intact then you'll want to load your text using the %s specifier. After the text is loaded you can either solve this problem with Regular Expressions (not my forte) or write your own parser then parses each word individually and saves the paranthesis and words to a new cell array.
AFAIK, there is no canned routine capable of preserving arbitrary delimiters.
You'd have to do it yourself:
string = '(a (bee (cold down)))';
bo = string == '(';
bc = string == ')';
sp = string == ' ';
output = cell(nnz(bo|bc|sp)+1,1);
j = 1;
for ii = 1:numel(string)
if bo(ii)
output{j} = '(';
j = j + 1;
elseif bc(ii)
output{j} = ')';
j = j + 1;
elseif sp(ii)
j = j + 1;
else
output{j} = [output{j} string(ii)];
end
end
Which can probably be improved -- the growing character array will prevent the loop from being JIT'ed. The array bc | bo | sp holds all the information to vectorize this thing, I just don't see how at this hour...
Nevertheless, it should give you a place to start.
Matlab has a strtok function similar to C. Its format is:
token = strtok(str)
token = strtok(str, delimiter)
[token, remain] = strtok('str', ...)
there is also a string replace function strrep:
modifiedStr = strrep(origStr, oldSubstr, newSubstr)
What I would do is modify the original string with strrep to add in delimiters, then use strtok. Since you already scanned the string into c:
c = (c,'(','( '); %Add a space after each open paren
c = (c,')',' ) '); % Add a space before and after each close paren
token = zeros(10); preallocate for speed
i = 2;
[token(1), remain] = strtok(c, ' ');
while(remain)
[token(i), remain] = strtok(c, ' ');
i =i + 1;
end
gives you the linear token array of each of the string you requested.
strtok reference: http://www.mathworks.com/help/techdoc/ref/strtok.html
strrep reference: http://www.mathworks.com/help/techdoc/ref/strrep.html

How to use XOR to Encrypt a music file

I want to encrypt and decrypt 10000 bytes of a music file. I used the code :
if(file!=NULL && g!= NULL)
{
while(!feof(file))
{
count++;
char aByte;
fread(&aByte, sizeof(char), 1, file);
if (count <= 10000)
{
if (count % 2 == 0)
{
if ((aByte ^ 'A') != EOF) aByte = aByte ^ 'A';
}
else
{
if ((aByte ^ 'B') != EOF) aByte = aByte ^ 'B';
}
}
fwrite(&aByte, sizeof(char), 1, g);
}
}
fclose(file);
But the code does not work. Please help!!!
You shouldn't do the XOR when you're checking for EOF (which, by the way, fread indicates in its return value rather than in the value it writes to your buffer); only when you're preparing the byte to be written to the file.
Also, you'll need a much longer key if you want to encrypt it properly — and the key must be unknown to anyone who isn't supposed to be able to decrypt it.
Test your file handling by removing the "encryption". Take out these lines
if (count % 2 == 0)
{
if ((aByte ^ 'A') != EOF) aByte = aByte ^ 'A';
}
else
{
if ((aByte ^ 'B') != EOF) aByte = aByte ^ 'B';
}
Is your file the exact same? I think it will not be. Here are some reasons
The file is longer than 10,000 bytes -- you close file at the end, so I assume that those bytes are lost
The file is less than 10,000 bytes -- you don't check for EOF property, so it looks like an extra byte will be written
count is not initialized in this code -- if it's odd on one run and even on another, it wont' match. Also, it's just going to copy a random number of bytes depending on what count is. Perhaps it's initialized elsewhere.
You don't close g, so you can't be sure it was flushed (fwrite can buffer writes)
UPDATE: EOF is not a byte that you can find in a file, it's a special return value used by some FILE API functions (not fread).
The function getchar() is defined like this:
int getchar();
It either returns EOF or an int that is within the range of char. If it's EOF, then that means that you are at the end of the file. If not, you may safely cast the return to a char. The only stipulation on EOF is that it isn't a valid char. getchar() returns an int because it can return any char (256 choices) + EOF for a total of 257 choices which can't be represented in a char.
If you look at fread(), you will see that it doesn't have anything to do with chars. It takes a buffer, and record size, and a record count and returns the number of bytes read. You happen to be passing in sizeof(char) and 1 to get a char. It couldn't possibly store EOF in that char because EOF is not a valid char, it's an int and won't fit. It doesn't use the same conventions as getchar(). If it encounters EOF, it returns a number less than the total number of bytes requested. In your case, that's 0. If fread() returns 0, check feof() and ferror() to find out if you got to the end-of-file or got an error (both cause fread to return less than the number requested).