Accessing data inside an array via pointer error - c++

I have 2 files in msg format. msg format is not important here.
car.msg
int speed;
int width;
cararr.msg
car mycar[];
I want to print all the information about all the cars that are present but I have no clue about the number of cars present(how big is the array) so I use the following technique to print the information.
so I do this:
cararr* ptr2car;
for(int i=0;mycar[i] != '\0'; i++){
cout << ptr2car->mycar[i].speed <<endl;
cout << ptr2car->mycar[i].width <<endl;
}
Despite this, I am receiving errors. I do not know what did I do wrong. I have no clue what approach should I use to get this output. please Help
Also why should I take a pointer to cararr, when I can just take an instance of cararr inst2car and do something like this:
cararr inst2car;
for(int i=0;mycar[i] != '\0'; i++){
cout << inst2car.mycar[i].speed <<endl;
cout << inst2car.mycar[i].width <<endl;
}
thanks

In general you need to know exactly what's at the end of the array. You need some sort of sentinel value to use as a delimiter to indicate the end of the array.
'\0' used in c strings is an example of such delimiter.
You need to ensure the last element in the array is such delimiter and check for it in the condition.
It's hard to give you more specific answer with such generic question.
For example, if you knew the last element will have speed -1, you can use that:
for(int i=0;mycar[i].speed != -1; i++) {

Related

Why does my function not switch the first character with the last one of my string?

I picked up a challenge on r/dailyprogrammer on reddit which wants me to match a necklace and put the last letter at the beginning of a string. I've considered using nested for loops for this but this has made me really confused.
Instead I chose the way of replacing the last with the first character in an if-statement. But I am not getting my desired output with it, though I've tried everything what comes into my mind.
I used even std::swap() which didn't lead me to success either.
Here's the code:
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
string same_necklace(string& sInput, string& sOutput)
{
for (string::size_type i = 0; i < sInput.size(); i++)
{
if (sInput[i] == sInput.size())
{
sInput[0] = sInput[sInput.size()];
}
}
for (string::size_type j = 0; j < sOutput.size(); j++)
{
if (sOutput[j] == sOutput.size() - 1)
{
sOutput[0] = sOutput[sOutput.size()];
}
}
return sInput, sOutput;
}
int main()
{
system("color 2");
string sName{ "" };
string sExpectedOutput{ "" };
cout << "Enter a name: ";
cin >> sName;
cout << "Enter expected output: ";
cin >> sExpectedOutput;
cout << "Result: " << same_necklace(sName , sExpectedOutput) << endl;
return 0;
}
And of course the link to my challenge (don't worry, it's just Reddit!):
https://www.reddit.com/r/dailyprogrammer/comments/ffxabb/20200309_challenge_383_easy_necklace_matching/
While I am waiting (hopefully) for a nice response, I will keep on trying to solve my problem.
In your if you compare the value of the current index (inside the loop) with the size of the string. Those are two unrelated things.
Also, you use a loop though you only want to do something on a single, previously known index.
for (string::size_type i = 0; i < sInput.size(); i++)
{
if (sInput[i] == sInput.size())
{
sInput[0] = sInput[sInput.size()];
}
}
You could change the if condition like this to achieve your goal:
if (i == sInput.size()-1) /* size as the index is one too high to be legal */
But what is sufficient and more elegant is to drop the if and the loop. completely
/* no loop for (string::size_type i = 0; i < sInput.size(); i++)
{ */
/* no if (sInput[i] == sInput.size())
{*/
sInput[0] = sInput[sInput.size()-1]; /* fix the index*/
/* }
} */
I.e.
sInput[0] = sInput[sInput.size()-1]; /* fix the index*/
Same for he output, though you got the correct index already correct there.
This is not intended to solve the challenge which you linked externally,
if you want that you need to describe the challenge completely and directly here.
I.e. this only fixes your code, according to the desription you provide here in the body of your question,
"put the last letter at the beginning of a string".
It does not "switch" or swap first and last. If you want that please find the code you recently wrote (surely, during your quest for learning programming) which swaps the value of two variables. Adapt that code to the two indexes (first and last, 0 and size-1) and it will do the swapping.
So much for the loops and ifs, but there is more wrong in your code.
This
return sInput, sOutput;
does not do what you expect. Read up on the , operator, the comma-operator.
Its result is the second of the two expressions, while the first one is only valuated for side effects.
This means that this
cout << "Result: " << same_necklace(sName , sExpectedOutput) << endl;
will only output the modified sExpectedOutput.
If you want to output both, the modified input and the modified output, then you can simply
cout << "Result: " << sName << " " << sExpectedOutput << endl;
because both have been given as reference to the function and hence both contain the changes the function made.
This also might not answer the challenge, but it explains your misunderstandings and you will be able to adapt to the challenge now.
You have not understand the problem i guess.
Here you need to compare two strings that can be made from neckless characters.
Lets say you have neckless four latters word is nose.
Combination is possible
1)nose
2)osen
3)seno
4)enos
your function (same_necklace) should be able to tell that these strings are belongs to same necklace
if you give any two strings as inputs to your function same_necklace
your function should return true.
if you give one input string from above group and second input string from other random word thats not belongs to above group, your function should return false.
In that sense, you just take your first string as neckless string and compare other string with all possible combination of first string.
just move move you first latter of first input string to end and then compare each resulting string to second input string.
below is the function which you can use
void swap_character(string &test)
{
int length = test.length();
test.insert(length, 1, test[0]);
test.erase(0, 1);
}

C++ string number of occurence

This is my first time asking something on stackoverflow, so I'm sorry if I fail in any aspect of building the topic etc...
So I'm a newbie at C++, I'm still at the beginning. I'm using a guide someone recommended me, and I'm stuck in a exercise which is about char and strings.
It's the following: They ask me to create a function that says the number of times that a certain word was repeated on a string.
I'll leave my code below for someone who can help me, if possible dont give me an obvious response like the code and then I just copy paste it. If you can just give me some hints on how to do it, I want to try to solve it on my own. Have a good night everyone.
#include <iostream>
#include <string.h>
#define MAX 50
using namespace std;
int times_occ(string s, string k) {
int count = 0, i = 0;
char word[sizeof(s)];
// while (s[i] == k[i])
// {
// i++;
// if (s[i] == '\0')
// {
// break;
// }
// }
for (i = 0; i <= sizeof(s); i++) {
if (s[i] == ' ' || s[i] == '\0') {
break;
}
word[i] = s[i];
}
word[i] = '\0';
for (i = 0; i <= sizeof(k); i++) {
if (word) {
if (k[i] == word[a]) {
a++;
count++;
}
}
}
cout << word << endl;
cout << count << endl; // this was supposed to count the number of times
// certain word was said in a string.
return count;
}
int main() {
char phrase[MAX];
char phrase1[MAX];
cin.getline(phrase, MAX);
cin.getline(phrase, MAX);
times_occ(phrase, phrase1);
}
Okay, first of all, the way you've used sizeof isn't really valid.
sizeof won't tell you the length of a string. For that, you want std::string::size() instead.
In this case, std::string is an object of some class, and sizeof will tell you the size of an object of that class. Every object of that type will yield the same size, regardless of the length of the string.
For example, consider code like this:
std::string foo("123456789");
std::string bar("12345");
std::cout << sizeof(foo) << "\t" << foo.size() << "\n";
std::cout << sizeof(bar) << "\t" << bar.size() << "\n";
When I run this, I get output like this:
8 9
8 5
So on this implementation, sizeof(string) is always 8, but some_string.size() tells us the actual length of the string.
So, that should at least be enough to get you started moving in a useful direction.
As #JerryCoffin mentioned, your word array has an invalid size. But - I want to make a more fundamental point:
Your code has two loops and a bunch of variables with arbitrary names. How should I know what's the difference between s and k? I even get k and i mixed up in the sense of forgetting that k is a string, not an integer. That kind of code difficult to read, and to debug. And we are a bit lazy and don't like debugging other people's code...
I suggest that you:
Have a very clear idea what your loops do, or what the different parts of your function do.
Create small self-contained functions - no more than one loop each please! - for each of those parts.
Use meaningful names for each function's parameters and for the local variables.
And then, if your program doesn't work - try debugging one function at a time.

compiler adding random characters to my char array

I have a function called SearchArray() which calls another function called SearchRecords(char StudentNo[]) to check the database array of gRecs for a match in student numbers.
When i run the debugger the value of StudentNo is being shown as StudentNo = 0x22fde0 "12345678" if StudentNum = "12345678".
What are these additional characters?
SearchArray() function
void SearchArray(){
char studentNum[8];
cout << "Enter student number: ";
cin >> studentNum;
char i = SearchRecords(studentNum);
if (gRecs[i].studentNumber != studentNum){
cout << "Record not found" << endl;
}
else {
PrintRecord(i);
}
}
SearchRecords() function
int SearchRecords(char StudentNo[])
{
for (int i = 0; i < gNumRecs; i++){
if(gRecs[i].studentNumber == StudentNo)
{
return i;
}
}
return -1; //not found
}
Do you mean the "0x22fde0"? Those aren't in your character array, your character array only contains the part in quotes ("12345678"). The hexadecimal number 0x22fde0 is the address of the first character. In C/C++, any array is really just a pointer to the first element: the value of the variable is the address of the first element. So the debugger is showing you that address value. But it also knows that character arrays usually store strings, so it is also helpfully showing you the contents of that array as a string.
As this comment notes, you're comparing pointers not strings. You'll save yourself many headaches by changing your studentNumber type to std::string. This will allow you to use comparison operators(==,!=,<,<=,>,>=) with either a std::string or a raw string(char*) on the right side. I highly recommend reading up on strings at tutorialspoint.com and cplusplus.com.
When posting in the future, please post any relevant custom data structures(such as the layout of your gRecs element type), it helps us solve the problem faster.

Unexpected array behavior in basic averaging program

It seems like I always come here to ask silly questions, but here it goes. As of right now I am in my first compsci course and we are learning c++. I've had an extremely basic introduction to c before, so I had thought I'd go above and beyond my current assignment. Now I was doing this just to showboat, I felt like if I didn't practice my previous concepts they would eventually fade. Anyways, on to the problem! I was supposed to write some code that allowed the user to input their initials, and a series of exams. Now this was supposed to accomplish three things: average the exams, print out the entered exams, and print out their initials. Well, what was a simple assignment, got turned into a huge mess by yours truly.
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
int main()
{
string uInitials;
float avgExam = 0, tExam = 0;
int aExams[10] = {'0'};
int i, nExam = 0, cExam;
cout << "Enter your three initials!";
cin >> uInitials;
do
{
cout << "Enter your exam(s) to be averaged. Enter 0 when complete!\n";
cin >> cExam;
aExams[nExam] = cExam; //I used this before nExam was incremented, in order to get nExam while it was '0' That way the first exam score would be properly saved in the first space
nExam++;
tExam += cExam; //This is just to add all the exams up to later calculate the average
}
while(cExam != 0);
avgExam = tExam/(nExam - 1); //subtracted '1' from nExams to remove the sentinel value from calculations.
cout << "The average for initials: " << uInitials << " is: " << avgExam << endl;
cout << "This average was obtained using the following scores that were entered: \n";
for(i = 0; i < (nExam+1); i++)
{
cout << aExams[i] << endl; //Used a for loop to prevent redundancy
}
return 0;
}
The previous is my code, and the problem is that I'm getting output errors where it adds two '0's when I print out the list of entered exams. Also I feel like I made the whole do{}while() loop one huge clunky mess, so I'd like to refine that as well. If anyone could assist this poor, ignorant, beginner I would greatly appreciate it. Thank you for your time!
Some advice that i can give is for example in the 5th line there is no need
to put the 0 between ' ' and not even need to use the assign = operator.
You can initialize the array like this:
int aExams[10]{0};
Which will initialize all elements to 0,but can't be used for other value.
For example you won't have all the elements with value 1 if you write
int aExams[10]{1};
If your intention to initialize all elements in an array is with value other than 0 you can use fill_n(); function.
fill_n(aExams, 10, 1);
The first argument is the name of the array, the second is up-to which element you want to be initialized with the third argument, and the third is the value you want all elements to have.
Do not leave uninitialized variables like in line 6 with cExam and i variables. Initialize it like cExam=0; (copy-assign initialization) or cExam(0); (direct initialization). The latter calls the constructor for int built-in type.
A negative i see in your do-while loop is that you do not make sure that the user will enter under 10 exams,bad things will happen if the user tries to input 15 exams in an array that can hold only 10.
Just change the while to something more like this:
while( cExam != 0 && (nExam<10) );
You can also write the first two lines of the do-while loop outside the loop.
It is needed only once to tell the user that to stop the loop he/she needs to enter 0. There is no need to tell them this on every iteration plus that you will have a good performance benefit if you put those two lines outside the loop.
Look here how i would write the code and ask if you have any questions.
http://pastebin.com/3BFzrk5C
The problem where it prints out two 0's at the end of your code is a result of the way you wrote your for loop.
Instead of:
for(i = 0; i < (nExam+1); i++)
{
cout << aExams[i] << endl; //Used a for loop to prevent redundancy
}
Use:
for (i = 1; i < (nExam); i++)
{
cout << aExams[i - 1] << endl; //Used a for loop to prevent redundancy
}

Length of string[] (number of elements in a string)

I want to cout my string, everything works as it should, but when the string is shown, it immediately shows me the "example_4578.exe has stopped running" error. I have noticed that the problem is in the i < str[32].length part, because when I change it to i < 3, it works without any problem. How should I solve this?
std::string str[32];
cin >> str[1];
cout << "str[1]=" << str[1] << endl;
cin >> str[2];
cout << "str[2]=" << str[2] << endl;
for (int i = 0; i < str[32].length; i++)
{
cout << str[i];
}
EDIT 1.
I've made a huge mistake. I actually want to find the "number" of elements/words in "str". In my example, I have only designed two cins. But I actually want to design a "for" loop later on, so that the user can input as many words as he wants, so if he inputs 4 words, I want that code to return those number of words to me. How should I do this? In other words, how can I find out how many elements are in "str"?
Couple of things:
C++ is 0-indexed. What this means is that std::string str[32] has indices that go from 0 to 31, and str[32] should not be accessed. This will cause a crash.
str[31].length() (which is presumably what you wanted) is the length of the last string, not the length of the array. The length of the array is 32, and your loop should read for(int i = 0; i < 32; i++).
The main problem is that you are accessing an element (number 32) that is out of the bounds (0 - 31). To solve this problem and not repeat it again in the future use a range-for loop:
std::string str[32];
for (auto s : str)
std::cout << s;
str[32].length is not what you think.
I guess you meant somthing like: length of a 32-elements array. Right?
What you've written is pointer to funciton length of 33rd element of array.
This is because the types are:
std::string str[32]; // `str` is 32-element array of `std::strings`
str[32]; // `std::string` taken from 33rd position in array `str` (arrays' indexing starts at 0)
std::string has a member function named size_t std::string::length(). When referenced by name, you get its address.
To achieve what you wanted, you'd need to write:
for (int i = 0; i < 32; i++) {
cout << str[i];
}
Unfortunately, plain arrays don't have length (or anything similar) built in. So, you'd either need to use a constant, or (better) use a container, such as std::vector.