Incrementing c structures

Started by
8 comments, last by Drew_Benton 14 years, 12 months ago
Hi I am programming in C I have made a structure for Car variables Is it possible to increment the structure that is read into from a scanf using a for loop. I.e for(i=0;i<CARS;i++) { scanf("%s",&Car.model); } I know the above does not work, just trying to illustrate what I am getting at. Something similar to reading into arrays. Anybody got any IDEAS?
Advertisement
Dreifach-Post: Eins. Zwei. Drei.
Quote:Original post by B G
I know the above does not work, just trying to illustrate what I am getting at.
Something similar to reading into arrays.


If model is a char array, then you don't need the &. Likewise, you just have to allocate a memory block of Car structures and then pass each individual member into the function.

For an example, consider this code:
#include <stdio.h>#include <memory.h>#include <stdlib.h>typedef struct{	char model[32];} Car;int main(int argc, char * argv[]){	int loopCtr;	int CARS = 0;	Car * cars = 0;	// Obtain CARS somehow	CARS = 3;	// Allocate memory and clear it out	cars = malloc(sizeof(Car) * CARS);	memset(cars, 0, sizeof(Car) * CARS);	// Loop through and get the input	for(loopCtr = 0; loopCtr < CARS; loopCtr++)	{		printf("Please enter car #%i's name: ", loopCtr + 1);		scanf("%31s", cars[loopCtr].model, 32);	}	// Verify the input	for(loopCtr = 0; loopCtr < CARS; loopCtr++)	{		printf("Car #%i's name is: %s\n", loopCtr + 1, cars[loopCtr].model);	}	// Cleanup our memory	free(cars);	// Standard return	return 0;}


You have to be careful though as using scanf can lead to a buffer overflow. What if someone typed in a name that was over 32 characters? Memory would be overwritten and your application could easily be compromised! That is why you have to set the width of the input string as well as pass the size of the buffer, to help keep your app safe.

For other non-array types, you do have to use the & before the variable so the contents are read into the 'address of' that variable. For arrays though, you do not have to as an array is already a pointer!
Quote:Original post by phresnel
Dreifach-Post: Eins. Zwei. Drei.


@B G: Could you please stop spamming the forums with triple posts and even more redundant posts like this one?

edit: I see you are spamming even more: your history of multi-posts.
Quote:Original post by phresnel
@B G: Could you please stop spamming the forums with triple posts and even more redundant posts like this one?


I think he has connection issues. A particular forum I'm visiting is so slow loading pages after a post that I sometimes made five identical posts in a row by clicking the submit button that many times. :D
Quote:Original post by Konfusius
Quote:Original post by phresnel
@B G: Could you please stop spamming the forums with triple posts and even more redundant posts like this one?


I think he has connection issues. A particular forum I'm visiting is so slow loading pages after a post that I sometimes made five identical posts in a row by clicking the submit button that many times. :D


Happened to me, too. Hence I intended to not be offensive in my first post. But then I've seen yet another post with semantically the same content, but with a distinct text and a distinct title (see my links). Hmm. :D
@phresnel: I am not spamming. Our local server here is acting up today, that caused the resubmissions. I apologise for those unintentional errors.
As for the old similar posts, they are help wanted ads for game projects from months apart as you can see. My total posts from 2007, including today, is 25 approx. Please do not character assassinate me. Thank you.

@everyone:
I don't even know if its possible but I am looking to increment the structure variables, not the variables in the structure. So I am looking to increment the structure, not a char array in the structure. So from car1.manufacturer to car2.manufacturer etc. Is this possible?

@Drew Benton: This looks like a possible solution, but the code chokes on my compiler (borland c++, but I am coding in c) .. could you walk me through it a bit.

what are the mainpoints of this technique? ..
Do I have to use pointers? ..
where is cars declared in this example (here ..Car * cars = 0; ?) ?

Thanks
Quote:Original post by B G
@Drew Benton: This looks like a possible solution, but the code chokes on my compiler (borland c++, but I am coding in c) .. could you walk me through it a bit.


The scanf() call is wrong; the ', 32' should not be there at the end. scanf() does not know anything about "buffer sizes"; the '%31s' tells it to read at most 31 characters into 'model'.

Also, make sure that the compiler knows you want to compile C code. Not all C code is legal C++.

Quote:what are the mainpoints of this technique? ..


The loop counter is incremented, used as an index into the array, and the 'model' member is selected from that element. Since 'model' is already a char*, you do not need or want to take its address. Passing a char* to scanf() with a matching "%s" means "start writing characters at the given location and continue until there is whitespace". The "%31s" format specifier is like "%s" with a limit of 31 characters. This is one less than the array size of 'model', because there must be room for a null terminator.

Quote:Do I have to use pointers? ..


It depends on what you mean by "use pointers".
If you mean "allocate memory dynamically": No. You can just as easily use 'Car cars[CARS];'. However, by allocating the memory dynamically, you don't have to decide ahead of time how many cars there should be.
If you mean "write code that takes the address of variables or dereferences pointer variables": indexing into an array is the same thing as doing pointer arithmetic and dereferencing. :)

Quote:where is cars declared in this example (here ..Car * cars = 0; ?) ?


Yes.
Quote:Original post by B G
Is it possible to increment the structure that is read into from a scanf using a for loop.

I assume you meant to iterate over an array of structs? That can be done by incrementing a pointer (as long as your objects are stored contiguously, as is the case with an array), or by simply indexing into the array, as Zahlman already explained.

Just thought I'd point out the subtle difference in terminology here. You don't really increment the structs themselves. :)
Create-ivity - a game development blog Mouseover for more information.
Quote:Original post by Zahlman
Quote:Original post by B G
@Drew Benton: This looks like a possible solution, but the code chokes on my compiler (borland c++, but I am coding in c) .. could you walk me through it a bit.


The scanf() call is wrong; the ', 32' should not be there at the end. scanf() does not know anything about "buffer sizes"; the '%31s' tells it to read at most 31 characters into 'model'.


Hmm, I think it was supposed to be a scanf_s, but I see now that I missed the _s due to the MSDN example being wrong.

Quote:
Unlike scanf and wscanf, scanf_s and wscanf_s require the buffer size to be specified for all input parameters of type c, C, s, S, or [. The buffer size is passed as an additional parameter immediately following the pointer to the buffer or variable. For example, if reading a string, the buffer size for that string is passed as follows:

char s[10];

scanf("%9s", s, 10);

The buffer size includes the terminating null. A width specification field may be used to ensure that the token read in will fit into the buffer. If no width specification field is used, and the token read is too big to fit in the buffer, nothing will be written to that buffer.


I would assume now their example should be scanf_s("%9s", s, 10);. Nice catch though, I didn't realize it in my copy-pasting/editing frenzy. [lol]

This topic is closed to new replies.

Advertisement