D lang - Using read and readln() in the same program - d

I'm having a very strange issue with a D program. read(" %s", variable) works fine by itself and readln(variable) works fine by itself, but when I put the two together, readln() appears to be passed over. The error occurred using both gdc and dmd.
import std.stdio;
import std.string;
void main()
{
int x;
write("Enter a number: ");
readf(" %s", &x);
write("What is your name? ");
string name=chomp(readln());
writeln("Hello ", name, "!");
}
Output:
Enter a number: 5
What is your name? Hello !
However, if I comment out readf(" %s", &x), readln is called as I desire:
Enter a number: What is your name? hjl
Hello hjl!

This is a common mistake with the readf and scanf function from C too. readf is pretty exact about the format string and whitespace. With your string there, it reads the value then stops at the first whitespace it sees... which happens to be the newline.
If you were to do this:
Enter a number: 123 bill
It would print What is your name? Hello bill! because it stopped at the space, then readln picked that up until end of line.
If you do 123, hit enter, then enter your name, readf stops at the newline character... which readln then picks up as an empty line.
Easiest fix is to just tell readf to consume the newline too:
readf(" %s\n", &x);
Then readln will be starting with an empty buffer and be able to get what it needs to get.

Related

The cin.ignore removing first character the second time function is being called

Can anyone tell me what is wrong with this? Without cin.ignore, the getline would not work, and after the first time when I call the function again, the first character is removed. So far I have tried using stringstream instead of getline, cin.sync(), cin.clear(), but nothing seems to work. Also the reason why I am using getline, is because some streets have spaces between them, so simply using cin would not work in this case
std::cout << "Enter Street Name 1: " ;
std::cin.ignore(1,EOF);
std::getline(std::cin,s1);
std::cout << "Enter Street Name 2: " ;
std::getline(std::cin,s2);
std::cout<<"Your first street was: "<<s1<<" Your second street was: "<<s2 <<". Please look at the map to find the intersection of " << s1 << " and " << s2 <<std::endl;
Output
Enter Street Name 1: Bloor
Enter Street Name 2: Yonge
Your first street was: Bloor Your second street was: Yonge. Please look at the map to find the intersection of Bloor and Yonge
Enter Street Name 1: Bloor
Enter Street Name 2: Yonge
Your first street was: loor Your second street was: Yonge. Please look at the map to find the intersection of loor and Yonge
Enter Street Name 1: Bloor
Enter Street Name 2: Uong
Your first street was: loor Your second street was: Uong. Please look at the map to find the intersection of loor and Uong
Without cin.ignore, the getline would not work,
That is true only if there is some code before that that leaves a newline character in the input stream.
and after the first time when I call the function again, the first character is removed.
That makes sense. cin.ignore() reads and discards one character.
I am not able to suggest something that will fix your problem without a Minimal, Complete, and Verifiable Example.
because you use cin.ignore() without parameters which means ignore the next char in the buffer that's why the first character is removed. To use cin.ignore()
cin.ignore( int nCount = 1, int delim = EOF );
Parameters
nCount - The maximum number of characters to extract.
delim - The delimiter character (defaults to EOF).
example
std::cin.ignore(256,' '); // ignore until space

String find, replace, and append algorithm in C++

I need to use getline(infile, aSentence) on 4 different sentences in a file and store them as strings. Then, I have to create an algorithm to move the first letter of every word to the last letter, then append "ay" the the word.
For example: "you may call me claptrap" will become "ouyay aymay allcay emay laptrapcay"
What's the best way to do this? I was thinking about using aSentence.find(" ") for the white space and aSentence.append to add "ay". I have no idea how to move the letter position though.
Hopefully this makes sense, thanks.
Code I have so far (incomplete, but it's the concept):
int characterIndex = 0;
char firstChar = sentence.at(characterIndex);
char currentChar = sentence.at(characterIndex);
while (currentChar != '.');
{
if(currentChar == ' ')
{
sentence.replace(characterIndex, "ay")
}
}
First thing is to write your function prototype
std::string toPigLatin(const std::string &english);
Now write a unit test for it. Pass in Hello world! and get back elloHay orlday! or whatevery you should get.
Now get it it through the unit test. If you pass an index variable i through the english, and append to the pig Latin, then i can be in three states, off-word (in whitespace or punctuation), on word, or on initial letter. We can have 1 letter words so we can go from on initial letter to off-word, but not from off-word to on-word, we have to go through the initial letter state.
When you enter the initial letter state, store the letter in a temporary. When you go into the off-word state, write it out and append an "ay". Otherwise write out the character you just read. Initial state is off-word.

Printing promt before user input

I am new to OCaml, and now I am trying to make a simple REPL.
let rec repl () =
print_prompt () ;
let input = Scanf.scanf "%s" (fun x -> x) in
if input = "" then repl ()
else print_endline input
let print_prompt () = print_string "> "
The problem now i am having is: when program starts, it does not display prompt immediately. It waits for my input and prints prompt along with my input.
What I want is:
> "user_input"
"user_input"
But i am getting :
"user_input"
> "user_input"
How can I fix this?
Using readline instead of Scanf :
val read_line : unit -> string
Flush standard output, then read characters from standard input until a newline character is encountered. Return the string of all characters read, without the newline character at the end.
Well, you didn't show the print_promt implementation, but I can guess, that it uses some buffered io function like print_string or printf. They print into an intermediate buffer and data will not be displayed unless flush is called. You can use flush or flush_all functions to do this manually. Also you can use a special specificator %! in printf formats string:
open Printf
let print_prompt () = printf "> %!"
This is almost certainly a buffering problem. In your print_prompt function, flush the standard output:
flush stdout

For scanf(), why is negated scanset "%[^\n]" showing correct output for "\n", but not the scanset "%[aeiou]" for "aegis"?

In the following program, if I use the line for the negated scanset, it works fine if I enter a multi-word line (ending with ENTER or newline), even though the newline is in the negated list.
But if I use the line for the scanset instead and enter the word "aegis" (or any word with consonants for that matter), then junk characters are output. Analogous to the first case, shouldn't at least "ae" be output if I enter this word? Please explain this behavior of scanset and negated scanset for scanf().
#include <stdio.h>
int main ()
{
char str[30];
printf("Enter the string\n");
//scanf("%[^\n]",str);
//scanf("%[aeiou]",str);
printf("%s",str);
}
It is because code errantly does not check the return value of scanf()
printf("Enter the string\n");
scanf("%[^\n]",str);
scanf("%[aeiou]",str); // check result before using `str`
printf("%s",str);
With scanf("%[^\n]",str); and input like "123\n", str get the values of "123" and '\n' remains in stdin. Then with scanf("%[aeiou]",str); and input like "aegis\n", the first line's '\n' blocks saving anything as '\n' is not a vowel, nothing is saved in str and since code did not check the return value of scanf(), does not realized that str may be invalid.
1) Always check the return value of scanf() and family.
if (scanf(some_format, var1, var2, ...) != ExpectedConversionCount) {
Fail();
}
2) scanf("%[^\n]",str); to read a line fails 3 things: No input limit, fails to read anything if the the line consists of only '\n'. Without check the return value, EOF is not detected.
3) Use fgets() instead of scanf() for user input.

c++ How to extract the whitespace between words if there is one

I've got two questions. I need to write a program that extracts all non-alphabetic characters and displays them, then removes them.
I am using isalpha which is working for symbols, but only if the input string has no spaces like "hello world"
but if it is more than one word like "hello! world!", it will only extract the first exclamation mark but not the second.
Second question which may be related, I want my program to detect the spaces between the words (I tried isspace but I must have used it wrong? and remove them and put them in a char variable
so for example
if the input is hello4 world! How3 are you today?
I want it to tell me
removed: 4
removed:
removed: !
removed:
removed: 3
removed:
removed:
removed:
long story short, if there is no other way, I'd like to detect spaces as !isalpha, or find something similar to isalpha for space between text.
Thanks
# include <iostream>
# include <string>
using namespace std;
void main()
{
string message;
cin >> message;
for (int i = 0; message[i]; i++)
if(!isalpha(message[i]))
cout << "deleted following character: " << message[i] <<endl;
else
cout <<"All is good! \n";
}
>> reads a single word, stopping when a whitespace character is found. To read a whole line, you want
std::getline(cout, message);
There is a better way by which you can get non-alphabetic characters,
You can check with asci value of each character and compare with alphabetic asci character if not in it & not a space (space asci val),
then you get your non-alphabetic character.
You can get all ascii codes over here :=> http://www.asciitable.com/
-Jayesh