Program isn't printing first digits of two strings - char

Hi I'm learning C through the Modern Approach book. For this program, we just need to input a first name and last name, and the program should return Last Name, First Initial.
char *first [255];
char *last [255];
printf("Enter a first name and a last name: ");
while (getchar() == ' ');
scanf("%s", first);
while (getchar() == ' ');
scanf("%s", last);
while (getchar() == ' ');
char firstInitial = (char) first[0];
printf("%s, ", last);
putchar(firstInitial);
When I run it, it doesn't print the first two characters.
e.g
Enter a first name and a last name: Aaron Smith
mith, a

This will get you started with getting the the first name.
#include <stdio.h>
int main() {
// Create a string
char firstName[255];
// Ask the user to input some text
printf("Enter your first name: \n");
// Get and save the text
scanf("%s", firstName);
// Output the text
printf("first name %s. 1st char %c", firstName, firstName[0]);
return 0;
}

#include <stdio.h>
void main()
{
char a = getchar();
char b;
scanf("%c",&b);
printf("%c",b);
}
Run the above code and see the result for yourself.
you can see that the getchar() function terminates only after when a “enter” key is pressed.
this causes an additional ‘\n’ character along with the single character you entered, to be in the input queue.
so character ‘b’ is assigned ‘\n’ and the compiler does not prompt you to provide input for ‘b’.

Related

Regexreplace - How to remove newlines located between parentheses?

I have a string of code that looks like
int main() {
double first, second, temp;
printf("Enter first number: ");
scanf("%lf", &first);
printf("Enter second number: ");
scanf("%lf", &second);
}
I want to run a Perl-compatible regex-replace to transform this code into
int main() {double first, second, temp;printf("Enter first number: ");scanf("%lf", &first);printf("Enter second number: ");scanf("%lf", &second);}
I've tried \n(?=[^{}]*}) but it only removes the new line preceding the {. Note that I do not want to remove any spaces or anything else. I only want to remove the new lines that are between the curly brackets.

Pointer not printing char[] array

I'm writing some code to take in a string, turn it into a char array and then print back to the user (before passing to another function).
Currently the code works up to dat.toCharArray(DatTim,datsize); however, the pointer does not seem to be working as the wile loop never fires
String input = "Test String for Foo";
InputParse(input);
void InputParse (String dat)
//Write Data
datsize = dat.length()+1;
const char DatTim[datsize];
dat.toCharArray(DatTim,datsize);
//Debug print back
for(int i=0;i<datsize;i++)
{
Serial.write(DatTim[i]);
}
Serial.println();
//Debug pointer print back
const char *b;
b=*DatTim;
while (*b)
{
Serial.print(*b);
b++;
}
Foo(*DatTim);
I can't figure out the difference between what I have above vs the template code provided by Majenko
void PrintString(const char *str)
{
const char *p;
p = str;
while (*p)
{
Serial.print(*p);
p++;
}
}
The expression *DatTim is the same as DatTim[0], i.e. it gets the first character in the array and then assigns it to the pointer b (something the compiler should have warned you about).
Arrays naturally decays to pointers to their first element, that is DatTim is equal to &DatTim[0].
The simple solution is to simply do
const char *b = DatTim;

C++ structure string and integer input

I wrote the following simple C++ structure implementation to see the usage of pointer to structure.
#include <iostream>
struct Employee
{
std::string name;
std::string sex;
int e_id;
}emp[2];
void printEmployee(struct Employee *e)
{
std::cout << e->name << std::endl;
std::cout << e->sex << std::endl;
std::cout << e->e_id << std::endl;
}
int main(int argc, char const *argv[])
{
struct Employee *e_ptr;
e_ptr = emp;
for (int i = 0; i < 2; ++i)
{
std::getline(std::cin, emp[i].name);
std::getline(std::cin, emp[i].sex);
std::cin >> emp[i].e_id;
}
for (int i = 0; i < 2; ++i)
{
printEmployee(e_ptr+i);
std::cout << std::endl;
}
return 0;
}
The inputs are
John Smith
male
123
Sarah Collin
female
After these input the program shows the output although the code is supposed to take one more input. The output is
John Smith
male
123
Sarah Collin
0
But If I don't include int e_id as a member then the code works perfectly.
This is from mixing getline and cin. Getline reads in the input until it hits a (generally) newline '\n'. It takes everything up to the newline, and throws away the newline.
cin reads until you hit white space (like, say, a newline), but doesn't throw it out of the stream. So, you type in 123 ENTER, meaning you have 123\n in the stream. Cin takes the 123 but leaves the \n.
Now you go back to the getline for employee name and immediately it sees the \n in the stream, which means it's done, and it throws it away. Out of curiosity, does it work if you type 123 SPACE instead of enter?
So what's actually happening is John Smith is good, male is good, 123 is good, but then the second employee's name is skipped, you typed Sarah Collin in for what was technically gender, then typed female for what was supposed to be e_id. Since female isn't an integer, what happens? Cin, by default, enters an error state and skips futher cin operations (you can also configure it to throw an exception). So really you actually never enter anything for the second e_id, and the 0 that you see is what it happened to be when it was created (you never initialized it, so it could actually be ANY value! Reading an uninitialized value is undefined behavior. Your compiler may help you out by setting ints to 0 for you, but that's not a kindness you can count on).
Here's someone else with your problem, and an example of how to use
cin.ignore();
to work around this. You need to manually ignore that newline character.
When and why do I need to use cin.ignore() in C++?
While reading integer std::cin stops when it encounters a character other than [+][-][0-9]. That is, std::cin stops at a character which cannot be included in a valid representation of an integer.
In the third line of input there are 4 characters are 123\n.
While reading std::string, std::getline stops reading characters when it encounters \n or delim characters. Also, std::getline does not store \n or delim characters in the string which is reads.
So, std::cin reads the integer emp[0].e_id as expected and stops at \n. After this std::getline reads \n and stops and stores nothing in emp[1].name

8051 sentence and word counter

I found this code below on the internet which is suppose to count the sentences on an 8051 MCU.
Can someone please explain to me what is exactly happening where there are question marks.
Any kind of help would be highly appreciated.
#include<string.h>
char code *text=" what is a program? that has, a a lot of errors! When " ;
char code *text1=" you compile. this file, uVision. reports a number of? ";
char code *text2=" problems that you! may interactively correct. " ; //Null characters are also included in array!!!
void count ( char pdata* , char pdata*);
void main (void){
char pdata Nw,Ns;
char data TextNw[2],TextNs[2];
count(&Nw, &Ns); // call subroutine
TextNw[0]=Nw/10; //?????????????????????????????????
TextNw[1]=Nw%10; //?????????????????????????????????
TextNs[0]=Ns/10; //?????????????????????????????????
TextNs[1]=Ns%10; //?????????????????????????????????
while(1);
}
void count ( char pdata *Nw, char pdata *Ns ){
unsigned char N, i, ch;
typedef enum {idle1, idle2} state; //?????????????????????????????????
state S; // begining state
P2=0x00; // pdata bank definition it must be performed first!!
*Ns=*Nw=0; // without proper start-up there is no initialisation, initialise now!!
S=idle1; // beginning state
N=strlen(text)+strlen(text1)+strlen(text2)+3; //????????????? + 3 to acount 3 Null characters!
P2=0x00; // pdata bank definition
for(i=0;i!=N;i++){
ch=text[i]; // take a caharacter from the text
switch (S)
{
case (idle1):{
if (ch==0) break; // skip NULL terminating character!
if (ch!=' '){
S=idle2;
(*Nw)++;
}
break;
}
case(idle2):{
if (ch==0) break; // skip NULL terminating character!
if((ch==' ')||(ch==','))S=idle1;
else if ((ch=='?')||(ch=='.')||(ch=='!')){
S=idle1;
(*Ns)++;
}
break;
}
}
}
}
This program does 2 things in conjunction - counts number of sentences in the text and counts the number of words in the text. Once the counting is done, the results are stored in 2-char arrays. For example, for 57 words in 3 sentences the results will be stored as this: TextNw = {'5','7'} and TextNs = {'0','3'}.
The variable N contains the full length of the text with the addition of 3 null terminating characters (one per sentence).
The algorithm simultaneously counts words and sentences. In idle1 state the counting is in word-counting mode. In idle2 state the counting is in sentence-counting mode. The modes are interchanged according to current character being read - if delimiter is encountered, the appropriate counter is increased.

scanf,fgets, fgetc get skipped inside loop

Im trying to make a recursive menu.
This program will later work with a tree(hojanodo), thats why I keep track of the root.
Problem: For some reason the fgets/fgetc is being skipped inside the recursivity on the second run, why does this happen?
I want the user to input either 1,2 or 3.(int)
What would be the fix for this? and is this the best way to implement a menu?
Here's what I have right now:(It compiles and runs so you can test it out but doesn't really work like I would like to..)
#include<stdio.h>
#include<stdlib.h>
typedef struct node{
char ch;
int i;
struct node *left;
struct node *right;
}hojaNodo;
int handle_menu(int eventHandler, hojaNodo **root);
int opcion_menu();
char get_symbol();
int get_userMenuInput();
int intro();
int main(){
hojaNodo *treeRoot = NULL;
intro();
// system("clear");
handle_menu(opcion_menu(), &treeRoot);
return 0;
}
int opcion_menu(){
int userOption;
printf("1.Agrega un Simbolo.\n");
printf("2.Listar Codigo\n");
printf("3.Exit");
userOption = get_userMenuInput();
printf("User: %d",userOption);
if(userOption < 4 && userOption > 0){
return userOption;
}
else
return -1;
}//eof opcion_menu
int handle_menu(int userOption,hojaNodo **root){
hojaNodo *tempRoot = NULL;
tempRoot = *root;
int valor;
char simbol;
switch(userOption){
case 1:
simbol = get_symbol();
printf("Simbol: %c", simbol);
break;
case 2:
printf("List Nodes\n");
break;
case 3:
printf("Exit");
userOption = -1;
// destroy_tree(root);
break;
default:
printf("userOption Error, Bye!");
break;
}//eof switch
if(userOption != -1)
handle_menu(opcion_menu(),&tempRoot);
// return userOption;
return -1;
}//eof menu()
char get_symbol(){
/*char userKey[3]
fgets(userKey,len,stdin);*/
char simbolo;
printf("Give me a symbol.");
simbolo = fgetc(stdin);
return simbolo;
}
int get_userMenuInput(){
char userKey[3];
int userOption;
size_t len;
len = sizeof(userKey);
fgets(userKey,len,stdin);
userOption = atoi(userKey);
//printf("User Option: %d\n", userOption);
return userOption;
}
Well apart from all the comments related to recursion and other changes suggested, please check this out. fgets() function needs flushing the input stream. It can be done using fflush() or fgetc().
A simple solution would be:
In function:
int opcion_menu(){
...
fgets(userKey,2,stdin);
fgetc(stdin); // Add this statement
Also in function:
int handle_menu(int userOption,hojaNodo **root)
case 1:
printf("Give me a choice : ");
fgets(userKey,2,stdin);
fgetc(stdin); // add this statement
fgets reads in at most one less than size characters from stream and stores them into the buffer pointed to by string. This will lead the newline character still available in Input Stream which need to be flushed. If this newline character is not read from Input stream, than this would become the input for next fgets function and ultimately it will skip the fgets(since it has already got its input a newline character)
fgetc(stdin) will flush out these extra newline character.
I don't know if this might help anyone.
In my case, I had to 'free' the buffer from the char with this function:
void clean(){
char cTemp;
while((cTemp = getchar()) != '\n')
;
}
Im not really sure why this works but it does(if anyone does, please add it to my answer).
I call it right before I call get_userOption();

Resources