c++ c-strings, strncat, strncpy - c++

This program is supposed to input someones name and output it like " Last, first middle". The names are supposed to be stored in 3 different arrays and their is a fourth array for the full name at the end. I am also supposed to use strncpy and strncat to build the fourth array. My issue im having is i dont know what the use of strncpy would be in this situation and how to use it. I can make the program say "first middle last" but not the correct output. Another issue im having is the while loop is supposed to allow the user to say 'q' or 'Q' and quit the program but it doesnt do this
#include <iomanip>
#include <iostream>
#include <cctype>
using namespace std;
int main()
{
char replay; //To hold Q for quit
const int SIZE = 51;
char firstName[SIZE]; // To hole first name
char middleName[SIZE]; // To hold middle name
char lastName[SIZE]; // To hold last name
char fullName[SIZE]; //To hold the full name
int count = 0;
int maxChars1;
int maxChars2;
cout << "Enter Q to quit or enter your first name of no more than " << (SIZE - 1)
<< " letters: ";
cin.getline(firstName, SIZE);
while(firstName[SIZE] != 'Q' || firstName[SIZE] != 'q')
{
cout << "\nEnter your middle name of no more than " << (SIZE - 1)
<< " letters: ";
cin.getline(middleName, SIZE);
cout << "\nEnter your last name of no more than " << (SIZE - 1)
<< " letters: ";
cin.getline(lastName, SIZE);
maxChars1 = sizeof(firstName) - (strlen(firstName) + 1);
strncat(firstName, middleName, maxChars1);
cout << firstName << endl;
maxChars2 = sizeof(lastName) - 1;
strncpy(firstName, lastName, maxChars2);
lastName[maxChars2] = '\0';
cout << lastName << endl;
}
system("pause");
return 0;
}

Your while loop doesn't work because of several reasons:
You're actually looking one past the end of the firstName array (firstName[SIZE]) rather than the first character (firstName[0]).
You're not checking to make sure firstName is only a single character q or Q.
You're only asking for the first name one time, before the loop, instead of every loop.
Your call to strncpy doesn't look right. As written, you're taking the last name and copying it to firstName, destroying the first and middle names that you just concatenated together there. Like #steve-jessop said, assemble the full name in fullName.
You're probably supposed to use strncpy and strncat because this is a contrived example/exercise where the buffer taking the full name is of a restricted size, so some name combinations will not fit, and need to be truncated.

Related

How do I get specific char from an array so that i can put into another array [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
im new to c++
Basically I have been asked to write a program that asks for the first name initial, middle name initial and the whole of the surname and output the first name initial on one line, middle name initial on another and surname on another. I did one program at first but the input was't taken all in one line and im not sure how to do this, sorry if my explanation isn't very helpful.
what i was asked to do
Write a program to prompt the user to enter in a single line their first name initial, followed by a space, their middle name initial followed by a space and the entirety of their surname. Store this in a char array. 
 
The program should then output the first initial on one line, then the middle initial on a separate line and the surname on a line of its own. 
 
This program is to demonstrate the use of char arrays. Ensure that you complete this program using a char array and that the data input by the user is stored in a single char array. You can separate out the various parts of the name into separate arrays afterwards, but the initial read from the console should put the entirety of the input into a single char array. 
#include <iostream>
using namespace std;
int main()
{
char firstNameInitial[2];
char middleNameInitial[2];
char surname[11];
cout << "Enter your first name initial: ";
cin >> firstNameInitial;
cout << "Enter your middle name initial: ";
cin >> middleNameInitial;
cout << "Enter your surname initial: ";
cin >> surname;
cout << firstNameInitial << endl << middleNameInitial << endl << surname << endl;
system("pause");
return 0;
}
this is what i did at first but the input are on different lines how would i do it in 1 while having output in different
How do I get a specific char from an array so that I can put it into
another array?
This is how arrays are taught to beginners. Be thorough with the basics of arrays and usage of indexes to access the array elements and hence solve your problem. You can refer to this tutorial.
Solution
You can solve your task in many ways. I will show you a solution using the fgets function. Moreover, you don't need any additional variables to separate the input. You can perform both read and display operations just by using a single array if you have some basic knowledge of array manipulation by now.
#include <iostream>
// Modify this according to your requirements
#define NAME_SIZE 30
int main()
{
// A single character array as per the constraints
char name[NAME_SIZE];
// Do it in the C-style!
fgets(name, NAME_SIZE, stdin);
// First initial
std::cout << name[0] << '\n';
// name[1] is the space that follows
// Second initial
std::cout << name[2] << '\n';
// name[3] is the space that follows
// Display the surname which starts at index 4
// Remember that the string terminates with a null character
for (unsigned i = 4; name[i] != '\0'; ++i) std::cout << name[i];
// Success
return 0;
}
What was required and is not is your current code (emphasize mine):
... prompt the user to enter in a single line...
Your current program uses 3 different prompts and most user will answer each element on its own line.
Ensure [...] that the data input by the user is stored in a single char array.
You are using 3 distinct char arrays for the input.
Hint: to have line oriented input in C++, the key has name getline. And has you are required to only use char arrays, you should use istream::getline
constexpr int SIZE = 32;
...
char line[SIZE];
cout << "Enter first name initial, a space, middle name initial, a space and your last name\n";
cin.getline(line, SIZE);
...
There are then different ways to split the input line in 3 pieces. Here I will assume (and control) that input was as expected:
if ((line[0] == ' ') || (line[1] != ' ') || (line[2] == ' ') || (line[3] != ' ') {
cerr << "Incorrect input" << endl;
return 1;
}
char *firstinitial = line;
firstinitial[1] = '\0'; // ensure null termination
char *midinitial = line + 2
midinitial[1] = '\0';
char *lastname = line + 4;
for(char *ix = line; ix<line+SIZE; ix++) { // ensure last name is null terminated
if (*ix == '\n') {
*ix = '\0';
break;
}
}
line[line+SIZE-1] = '\0' // if SIZE characters were read
cout << "First name initial is: " << firstinitial << '\n';
cout << "Middle name initial is: " << midinitial << '\n';
cout << "Last name is: " << lastname<< '\n';

how to subtract first and last letter of a string

First of all i am new in programming.
I was asked to create a program that prompts the user to insert a word and then I translate it into some sort of fake language.
So i make the following:
firstLetter of the new word is the last char of the original word
secondLetter is ncy
thirdLetter is the entered word without the first and last char
fourthLetter is nan
fifthLetter is the first character of the word
e.g. user enters= dog
new word is: gncyonand
My code is this but its failing and I assume is because the string does not exist yet(the user still has to insert it). Please help:
**
#include <iostream> //for cin and cout
#include <string> //for string data
using namespace std;
int main()
{
//I add a welcome message:
std::cout << "*************************************************\n"
<< " Welcome to Nacy-latin converter program\n"
<< "*************************************************\n\n";
// I declare first string:
std:: string userWord; //the word the user imputs
std::string firstLetter= userWord.substr(-1,0); //last char of the entered word
std::string secondLetter = "ncy";
std::string thirdLetter= userWord.substr(1, userWord.length() - 1); //last char of the entered word
std::string fourthLetter = "nan"; //just nan
std::string fifthLetter= userWord.substr(0,1); ; //the first char of the userWord
//I ask the user to imput data:
cout << "Hey there!";
cout << endl<<endl;
cout << "Please enter a word with at least two letters and I will converted into Nacy-latin for you:\n";
//return data to the user:
cout<<"The word in Nancy-Latin is:" <<firstLetter << secondLetter << thirdLetter <<fourthLetter <<fifthLetter<<'\n';
// Farewell message
cout << "\nThank you for the 'Nancy-latin' converter tool!\n";
// system(“pause”);
return (0) ;
}
**
Did you use Python before? std::string does not allow negative indexes. You can use a mix of front(), back(), and substr() string methods to get individual pieces and then use the C++ class std::stringstream to build your new string.
std::stringstream ss;
ss << userWord.back() << "ncy";
ss << userWord.substr(1, userWord.size() - 2);
ss << "nan" << userWord.front();
std::cout << ss.str();
Do not forget to check user input for at least two characters.
Alternative to make new word in place.
std::swap(userWord.front(), userWord.back());
userWord.insert(1, "ncy");
userWord.insert(userWord.size() - 2, "nan");
std::cout << userWord;

Transversing an Array of structs error in C++

Current code:
const int MAX_CODENAME = 25;
const int MAX_SPOTS = 5;
struct Team {
string TeamName[MAX_CODENAME];
short int totalLeagueGames;
short int leagueWins;
short int leagueLoses;
};
//GLOBAL VARIABLES:
Team league[MAX_SPOTS];
void addTeams(){
int i = 0; //first loop
int j; //second loop
while(i < MAX_SPOTS){
cout << "****** ADD TEAMS ******" << endl;
cout << "Enter the teams name " << endl;
scanf("%s", league[i].TeamName) ;
}
void searchTeam(){
string decider[MAX_CODENAME];
cout << "Please enter the team name you would like the program to retrieve: " << endl;
cin >> decider[MAX_CODENAME];
for(int i = 0; i < MAX_SPOTS; i++){
if(decider == league[i].TeamName){
cout << endl;
cout << league[i].TeamName << endl;
break;
}else{
cout << "Searching...." << endl;
}
}
}
I really dont know why its not working but I have included all the perquisite header files such as and but the program crashes when i enter the data and then attempt to search. I get the circle of death and then program not responding then says Process returned 255 (0xFF) . It does not even out put Searching.... the program practically gives up as soon as I enter that name.
Also if this can be optimized by the use of pointers that would be great.
tl;dr run-time error causing the search to fail as soon as i type in a name. And for the record I have checked to make sure the name I entered is valid.
scanf doesn't know about std::string. Use std::cin >> league[i].TeamName.
scanf("%s", league[i].TeamName) ;
This should be changed to
std::cin >> league[i].TeamName ;
A couple of other things here....
string decider[MAX_CODENAME];
cout << "Please enter the team name you would like the program to retrieve: " << endl;
cin >> decider[MAX_CODENAME];
Every time you input a value, you are telling the computer to hold the inputted value at decider[25] but the computer only reads indexes 0-24.
if(decider == league[i].TeamName){
Which array slot are you comparing the team name to? If its the 25th element than the statement should be
if(decider[24] == league[i].TeamName){
Pointers are better suited if the number of TeamNames are unknown. Based on the limited code presented, I highly recommend you stay within the realm of basic data types. For the purposes of troubleshooting, please post your full code in the future.
Your TeamName member variable:
string TeamName[MAX_CODENAME];
is an array of 25 strings, so in this line:
scanf("%s", league[i].TeamName) ;
you are courrupting the array. You don't really want an array anyways, so change the TeamName declaration to:
string TeamName;
and then when you read the name, you'll need to use iostreams which knows how to populate a string type (scanf only works with c char arrays):
std::cin >> league[i].TeamName

how to store character variable into two dimensional character variable

I Want to store the value of user_uname and user_pwd to validuser[c][0] and validuser[c][1].Also string "normaluser" to validuser[c][2].
But it shows an error "cannot convert char * to char".This is my code:
char validuser[20][20];
int c;
char user_uname[20],user_pwd[20];
cout<<"\n Enter User Detail";
cout<<"\n enter Username:";
cin>>user_uname;
cout<<"\n Enter Password:";
cin>>user_pwd;
validuser[c][0] = user_uname;
validuser[c][1] = user_pwd;
validuser[c][2] = "normaluser";
c++;
Your validuser is an array of arrays or chars. You can only store single char in each spot, or you can use it as an array of "strings" (char arrays). If you definitely want to use C style strings, you should have a third dimension to do what you're trying, such as char validuser[20][3][20].
But since you are using C++, why not use std::vector<std::string> rather? And store usernames and passwords in a struct, not as consecutive strings. Using C++ strings and vectors will allow you to use any length of strings or any number of users without knowing the number beforehand or handling memory allocations yourself.
char validuser[20][20];
....
validuser[c][0] = user_uname;
The validuser[][] is a char so you are not OK to assign. In your code, you can use:
strncpy( &(validuser[c][0]), user_uname, 20 );
But why dont you use the std::vector or std::array? In most of the case, std::string provide good enough feature for you.
You must use string on this. Char only accept a single character, here is the modified code. Hope this helps :)
The First Dimension you only need 3 array because of the user name, password, and type. for the 2nd Dimension you can add as many as you want, I made it 3 so that it would accept 3 users.
#include<iostream>
#include<string>
using namespace std;
void main()
{
int pause;
string validuser[3][3];
int c = 0;
do
{
string user_uname, user_pwd;
cout << "\nEnter User Detail";
cout << "\nenter Username:";
cin >> user_uname;
cout << "Enter Password:";
cin >> user_pwd;
cout << endl;
validuser[c][0] = user_uname;
validuser[c][1] = user_pwd;
validuser[c][2] = "normal_user";
c++;
} while (c < 3);
c = 0;
do{
cout << validuser[c][0] << " " << validuser[c][1] << " " << validuser[c][2] << endl;
c++;
} while (c < 3);
cin >> pause;
}

Recognize "010" and similar numbers as a palindrome using modulus in C++

First post! This is my second semester with "Advanced C & C++" so any help is GREATLY appreciated. I've already scoured as much of stackoverflow and a few other resources to try and help me understand what I'm doing (or not doing) with this slew of logically inept code.
The goal of this program is to recognize whether or not a 'number' given by the user is a palindrome. Sounds simple enough right?! Ugh...well this is what I have been stuck on:
#include <iostream>
using std::cout;
using std::cin;
#include <string>
using std::string;
#include <cstdlib>
int main()
{
//variable declarations
string buffer;
//user input
cout << "Enter a number to see if it is a palindrome[Q to quit]: ";
getline(cin, buffer);
//looooop
while(buffer != "Q" && buffer !="q")
{
int userNum, length, sum = 0, temp;
userNum = atoi(buffer.c_str());
for(temp = userNum; userNum !=0; userNum=userNum/10)
{
length = userNum % 10;
sum = sum*10+length;
}
if(temp==sum)
cout << temp << " is a palindrome!!\n\n";
else
cout << buffer << " is NOT a palindrome!\n\n";
cout << "Enter a number to see if it is a palindrome[Q to quit]: ";
getline(cin, buffer);
}
}
The problem arises when input of "010", or "400" is given. "400" is essentially "00400" in this case and both should be seen as a palindrome.
A better approach would be to get trailing zeros for the given number as below:
int noOfTrailingZeros = str.length;
while(str[--noOfTrailingZeros]=='0');
noOfTrailingZeros = str.length - noOfTrailingZeros;
Or the integer way as:
int noOfTrailingZeros = str.length;
while(num%10==0)
{
noOfTrailingZeros++;
num/=10;
}
Now, check for the input string whether it has the same number of zeros befire the number or not as:
int counterZeros = 0;
while(str[counterZeros++]=='0');
check these 2 numbers and if trailing zeros are more than the zeros at beginning, add that many at the beginning and pass that string to palindrome function.
First of all, to recognize a palindrome, you don't have to do atoi. Just pass from the start to the middle checking if
buffer[i] == buffer[length - i]
Second, use the atoi to make sure it is a number and you're done.
Other way is to compare the string with itself reversed:
string input;
cout << "Please enter a string: ";
cin >> input;
if (input == string(input.rbegin(), input.rend())) {
cout << input << " is a palindrome";
}