Structures with variable members size
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}
I want to write functions to get and print data entered by a user. Idea is to to have name and a last name as pointers, pointers to variable size strings. What is wrong with code? What am I doing wrong? Alternatives?
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char *name;
char *lastname;
int marks[5];
} Student;
void setS(Student *s);
void getS(Student *s);
int main()
{
Student st;
getS(&st);
setS(&st);
return 0;
}
void setS(Student *s){
int i;
printf("Name: %st", s->name);
printf("last Name: %st", s->lastname);
for(i=0; i<5; i++)
printf("%3d", s->marks[i]);
printf("n");
}
void getS(Student *s){
int i;
printf("Enter namen");
gets(s->name);
printf("Enter last namen");
gets(s->lastname);
printf("Enter marksn");
for(i=0; i<5; i++)
scanf("%d", &s->marks[i]);
printf("n");
}
c pointers structure
|
show 1 more comment
I want to write functions to get and print data entered by a user. Idea is to to have name and a last name as pointers, pointers to variable size strings. What is wrong with code? What am I doing wrong? Alternatives?
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char *name;
char *lastname;
int marks[5];
} Student;
void setS(Student *s);
void getS(Student *s);
int main()
{
Student st;
getS(&st);
setS(&st);
return 0;
}
void setS(Student *s){
int i;
printf("Name: %st", s->name);
printf("last Name: %st", s->lastname);
for(i=0; i<5; i++)
printf("%3d", s->marks[i]);
printf("n");
}
void getS(Student *s){
int i;
printf("Enter namen");
gets(s->name);
printf("Enter last namen");
gets(s->lastname);
printf("Enter marksn");
for(i=0; i<5; i++)
scanf("%d", &s->marks[i]);
printf("n");
}
c pointers structure
3
You never initialize either pointer to point at valid, sufficient memory. Yourgetscalls invoked undefined behavior
– UnholySheep
Jan 3 at 20:14
2
Also, don't usegets
– UnholySheep
Jan 3 at 20:15
Soooo, I should do...!?
– nnidza
Jan 3 at 20:17
1
Either allocate sufficient memory and limit user input to not be more than what you have or do something like in stackoverflow.com/questions/16870485/…
– UnholySheep
Jan 3 at 20:23
I understand, i think. Using malloc to allocate the memory, adding function for collectiing chars from the input and removing unwanted characters... All have to be in one...
– nnidza
Jan 3 at 20:48
|
show 1 more comment
I want to write functions to get and print data entered by a user. Idea is to to have name and a last name as pointers, pointers to variable size strings. What is wrong with code? What am I doing wrong? Alternatives?
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char *name;
char *lastname;
int marks[5];
} Student;
void setS(Student *s);
void getS(Student *s);
int main()
{
Student st;
getS(&st);
setS(&st);
return 0;
}
void setS(Student *s){
int i;
printf("Name: %st", s->name);
printf("last Name: %st", s->lastname);
for(i=0; i<5; i++)
printf("%3d", s->marks[i]);
printf("n");
}
void getS(Student *s){
int i;
printf("Enter namen");
gets(s->name);
printf("Enter last namen");
gets(s->lastname);
printf("Enter marksn");
for(i=0; i<5; i++)
scanf("%d", &s->marks[i]);
printf("n");
}
c pointers structure
I want to write functions to get and print data entered by a user. Idea is to to have name and a last name as pointers, pointers to variable size strings. What is wrong with code? What am I doing wrong? Alternatives?
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char *name;
char *lastname;
int marks[5];
} Student;
void setS(Student *s);
void getS(Student *s);
int main()
{
Student st;
getS(&st);
setS(&st);
return 0;
}
void setS(Student *s){
int i;
printf("Name: %st", s->name);
printf("last Name: %st", s->lastname);
for(i=0; i<5; i++)
printf("%3d", s->marks[i]);
printf("n");
}
void getS(Student *s){
int i;
printf("Enter namen");
gets(s->name);
printf("Enter last namen");
gets(s->lastname);
printf("Enter marksn");
for(i=0; i<5; i++)
scanf("%d", &s->marks[i]);
printf("n");
}
c pointers structure
c pointers structure
asked Jan 3 at 20:12
nnidzannidza
1
1
3
You never initialize either pointer to point at valid, sufficient memory. Yourgetscalls invoked undefined behavior
– UnholySheep
Jan 3 at 20:14
2
Also, don't usegets
– UnholySheep
Jan 3 at 20:15
Soooo, I should do...!?
– nnidza
Jan 3 at 20:17
1
Either allocate sufficient memory and limit user input to not be more than what you have or do something like in stackoverflow.com/questions/16870485/…
– UnholySheep
Jan 3 at 20:23
I understand, i think. Using malloc to allocate the memory, adding function for collectiing chars from the input and removing unwanted characters... All have to be in one...
– nnidza
Jan 3 at 20:48
|
show 1 more comment
3
You never initialize either pointer to point at valid, sufficient memory. Yourgetscalls invoked undefined behavior
– UnholySheep
Jan 3 at 20:14
2
Also, don't usegets
– UnholySheep
Jan 3 at 20:15
Soooo, I should do...!?
– nnidza
Jan 3 at 20:17
1
Either allocate sufficient memory and limit user input to not be more than what you have or do something like in stackoverflow.com/questions/16870485/…
– UnholySheep
Jan 3 at 20:23
I understand, i think. Using malloc to allocate the memory, adding function for collectiing chars from the input and removing unwanted characters... All have to be in one...
– nnidza
Jan 3 at 20:48
3
3
You never initialize either pointer to point at valid, sufficient memory. Your
gets calls invoked undefined behavior– UnholySheep
Jan 3 at 20:14
You never initialize either pointer to point at valid, sufficient memory. Your
gets calls invoked undefined behavior– UnholySheep
Jan 3 at 20:14
2
2
Also, don't use
gets– UnholySheep
Jan 3 at 20:15
Also, don't use
gets– UnholySheep
Jan 3 at 20:15
Soooo, I should do...!?
– nnidza
Jan 3 at 20:17
Soooo, I should do...!?
– nnidza
Jan 3 at 20:17
1
1
Either allocate sufficient memory and limit user input to not be more than what you have or do something like in stackoverflow.com/questions/16870485/…
– UnholySheep
Jan 3 at 20:23
Either allocate sufficient memory and limit user input to not be more than what you have or do something like in stackoverflow.com/questions/16870485/…
– UnholySheep
Jan 3 at 20:23
I understand, i think. Using malloc to allocate the memory, adding function for collectiing chars from the input and removing unwanted characters... All have to be in one...
– nnidza
Jan 3 at 20:48
I understand, i think. Using malloc to allocate the memory, adding function for collectiing chars from the input and removing unwanted characters... All have to be in one...
– nnidza
Jan 3 at 20:48
|
show 1 more comment
1 Answer
1
active
oldest
votes
What is wrong with code? What am I doing wrong?
gets(s->name); attempts to read user input into s->name. s->name is a char * that has not yet been assigned. gets() attempts to save data to who-knows-where? Result: undefined behavior (UB).
Alternatives?
Read into a buffer and then allocated memory for a copy.
Tip: As you can, avoid scanf(), gets() for user input and use fgets(). C - scanf() vs gets() vs fgets().
Some code to provide an idea.
#define NAME_N 100
// return 1 on success
// return EOF on end-of-file
// return 0 other errors
int getS(Student *s) {
*s = (Student) {NULL, NULL, {0}}; // pre-fill with default values.
char buffer[NAME_N];
printf("Enter namen");
if (fgets(buffer, sizeof buffer, stdin) == NULL) {
return EOF;
}
trim(buffer);
if (!validate_name(buffer)) {
return 0;
}
s->name = strdup(buffer);
printf("Enter last namen");
if (fgets(buffer, sizeof buffer, stdin) == NULL) {
return EOF;
}
trim(buffer);
if (!validate_name(buffer)) {
return 0;
}
s->lastname = strdup(buffer);
printf("Enter marksn");
for (int i = 0; i < 5; i++) {
if (fgets(buffer, sizeof buffer, stdin) == NULL) {
return EOF;
}
if (sscanf(buffer, "%d", &s->marks[i]) != 1) {
return 0;
}
}
return 1;
}
trim() is your function to trim leading/trailing/excessive white-spaces. See also How do I trim leading/trailing whitespace in a standard way?.
strdup() is not C standard yet very commonly available string duplication function that allocated memory and copies. Sample code
validate_name() is placeholder code to insure some sanity in the name. Be generous in what is acceptable. Commonly acceptable characters in a name include
[A-Z, a-z, '-', ''', ' ', '.'] and many others: What are all of the allowable characters for people's names?.
Example:
// Fail a zero length name or one with controls characters in it.
bool validate_name(const char *name) {
if (*name == '') return false;
while (*name) {
if (iscntrl((unsigned char) *name)) return false;
name++;
}
return true;
}
Thanks a lot. I tried using a tmp string of a fixed size (buffer in your case) but I used strcpy function, plus gets... I like your way of handling data. I will try it out tommorow. Thanks a lot!
– nnidza
Jan 3 at 22:22
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54029147%2fstructures-with-variable-members-size%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
What is wrong with code? What am I doing wrong?
gets(s->name); attempts to read user input into s->name. s->name is a char * that has not yet been assigned. gets() attempts to save data to who-knows-where? Result: undefined behavior (UB).
Alternatives?
Read into a buffer and then allocated memory for a copy.
Tip: As you can, avoid scanf(), gets() for user input and use fgets(). C - scanf() vs gets() vs fgets().
Some code to provide an idea.
#define NAME_N 100
// return 1 on success
// return EOF on end-of-file
// return 0 other errors
int getS(Student *s) {
*s = (Student) {NULL, NULL, {0}}; // pre-fill with default values.
char buffer[NAME_N];
printf("Enter namen");
if (fgets(buffer, sizeof buffer, stdin) == NULL) {
return EOF;
}
trim(buffer);
if (!validate_name(buffer)) {
return 0;
}
s->name = strdup(buffer);
printf("Enter last namen");
if (fgets(buffer, sizeof buffer, stdin) == NULL) {
return EOF;
}
trim(buffer);
if (!validate_name(buffer)) {
return 0;
}
s->lastname = strdup(buffer);
printf("Enter marksn");
for (int i = 0; i < 5; i++) {
if (fgets(buffer, sizeof buffer, stdin) == NULL) {
return EOF;
}
if (sscanf(buffer, "%d", &s->marks[i]) != 1) {
return 0;
}
}
return 1;
}
trim() is your function to trim leading/trailing/excessive white-spaces. See also How do I trim leading/trailing whitespace in a standard way?.
strdup() is not C standard yet very commonly available string duplication function that allocated memory and copies. Sample code
validate_name() is placeholder code to insure some sanity in the name. Be generous in what is acceptable. Commonly acceptable characters in a name include
[A-Z, a-z, '-', ''', ' ', '.'] and many others: What are all of the allowable characters for people's names?.
Example:
// Fail a zero length name or one with controls characters in it.
bool validate_name(const char *name) {
if (*name == '') return false;
while (*name) {
if (iscntrl((unsigned char) *name)) return false;
name++;
}
return true;
}
Thanks a lot. I tried using a tmp string of a fixed size (buffer in your case) but I used strcpy function, plus gets... I like your way of handling data. I will try it out tommorow. Thanks a lot!
– nnidza
Jan 3 at 22:22
add a comment |
What is wrong with code? What am I doing wrong?
gets(s->name); attempts to read user input into s->name. s->name is a char * that has not yet been assigned. gets() attempts to save data to who-knows-where? Result: undefined behavior (UB).
Alternatives?
Read into a buffer and then allocated memory for a copy.
Tip: As you can, avoid scanf(), gets() for user input and use fgets(). C - scanf() vs gets() vs fgets().
Some code to provide an idea.
#define NAME_N 100
// return 1 on success
// return EOF on end-of-file
// return 0 other errors
int getS(Student *s) {
*s = (Student) {NULL, NULL, {0}}; // pre-fill with default values.
char buffer[NAME_N];
printf("Enter namen");
if (fgets(buffer, sizeof buffer, stdin) == NULL) {
return EOF;
}
trim(buffer);
if (!validate_name(buffer)) {
return 0;
}
s->name = strdup(buffer);
printf("Enter last namen");
if (fgets(buffer, sizeof buffer, stdin) == NULL) {
return EOF;
}
trim(buffer);
if (!validate_name(buffer)) {
return 0;
}
s->lastname = strdup(buffer);
printf("Enter marksn");
for (int i = 0; i < 5; i++) {
if (fgets(buffer, sizeof buffer, stdin) == NULL) {
return EOF;
}
if (sscanf(buffer, "%d", &s->marks[i]) != 1) {
return 0;
}
}
return 1;
}
trim() is your function to trim leading/trailing/excessive white-spaces. See also How do I trim leading/trailing whitespace in a standard way?.
strdup() is not C standard yet very commonly available string duplication function that allocated memory and copies. Sample code
validate_name() is placeholder code to insure some sanity in the name. Be generous in what is acceptable. Commonly acceptable characters in a name include
[A-Z, a-z, '-', ''', ' ', '.'] and many others: What are all of the allowable characters for people's names?.
Example:
// Fail a zero length name or one with controls characters in it.
bool validate_name(const char *name) {
if (*name == '') return false;
while (*name) {
if (iscntrl((unsigned char) *name)) return false;
name++;
}
return true;
}
Thanks a lot. I tried using a tmp string of a fixed size (buffer in your case) but I used strcpy function, plus gets... I like your way of handling data. I will try it out tommorow. Thanks a lot!
– nnidza
Jan 3 at 22:22
add a comment |
What is wrong with code? What am I doing wrong?
gets(s->name); attempts to read user input into s->name. s->name is a char * that has not yet been assigned. gets() attempts to save data to who-knows-where? Result: undefined behavior (UB).
Alternatives?
Read into a buffer and then allocated memory for a copy.
Tip: As you can, avoid scanf(), gets() for user input and use fgets(). C - scanf() vs gets() vs fgets().
Some code to provide an idea.
#define NAME_N 100
// return 1 on success
// return EOF on end-of-file
// return 0 other errors
int getS(Student *s) {
*s = (Student) {NULL, NULL, {0}}; // pre-fill with default values.
char buffer[NAME_N];
printf("Enter namen");
if (fgets(buffer, sizeof buffer, stdin) == NULL) {
return EOF;
}
trim(buffer);
if (!validate_name(buffer)) {
return 0;
}
s->name = strdup(buffer);
printf("Enter last namen");
if (fgets(buffer, sizeof buffer, stdin) == NULL) {
return EOF;
}
trim(buffer);
if (!validate_name(buffer)) {
return 0;
}
s->lastname = strdup(buffer);
printf("Enter marksn");
for (int i = 0; i < 5; i++) {
if (fgets(buffer, sizeof buffer, stdin) == NULL) {
return EOF;
}
if (sscanf(buffer, "%d", &s->marks[i]) != 1) {
return 0;
}
}
return 1;
}
trim() is your function to trim leading/trailing/excessive white-spaces. See also How do I trim leading/trailing whitespace in a standard way?.
strdup() is not C standard yet very commonly available string duplication function that allocated memory and copies. Sample code
validate_name() is placeholder code to insure some sanity in the name. Be generous in what is acceptable. Commonly acceptable characters in a name include
[A-Z, a-z, '-', ''', ' ', '.'] and many others: What are all of the allowable characters for people's names?.
Example:
// Fail a zero length name or one with controls characters in it.
bool validate_name(const char *name) {
if (*name == '') return false;
while (*name) {
if (iscntrl((unsigned char) *name)) return false;
name++;
}
return true;
}
What is wrong with code? What am I doing wrong?
gets(s->name); attempts to read user input into s->name. s->name is a char * that has not yet been assigned. gets() attempts to save data to who-knows-where? Result: undefined behavior (UB).
Alternatives?
Read into a buffer and then allocated memory for a copy.
Tip: As you can, avoid scanf(), gets() for user input and use fgets(). C - scanf() vs gets() vs fgets().
Some code to provide an idea.
#define NAME_N 100
// return 1 on success
// return EOF on end-of-file
// return 0 other errors
int getS(Student *s) {
*s = (Student) {NULL, NULL, {0}}; // pre-fill with default values.
char buffer[NAME_N];
printf("Enter namen");
if (fgets(buffer, sizeof buffer, stdin) == NULL) {
return EOF;
}
trim(buffer);
if (!validate_name(buffer)) {
return 0;
}
s->name = strdup(buffer);
printf("Enter last namen");
if (fgets(buffer, sizeof buffer, stdin) == NULL) {
return EOF;
}
trim(buffer);
if (!validate_name(buffer)) {
return 0;
}
s->lastname = strdup(buffer);
printf("Enter marksn");
for (int i = 0; i < 5; i++) {
if (fgets(buffer, sizeof buffer, stdin) == NULL) {
return EOF;
}
if (sscanf(buffer, "%d", &s->marks[i]) != 1) {
return 0;
}
}
return 1;
}
trim() is your function to trim leading/trailing/excessive white-spaces. See also How do I trim leading/trailing whitespace in a standard way?.
strdup() is not C standard yet very commonly available string duplication function that allocated memory and copies. Sample code
validate_name() is placeholder code to insure some sanity in the name. Be generous in what is acceptable. Commonly acceptable characters in a name include
[A-Z, a-z, '-', ''', ' ', '.'] and many others: What are all of the allowable characters for people's names?.
Example:
// Fail a zero length name or one with controls characters in it.
bool validate_name(const char *name) {
if (*name == '') return false;
while (*name) {
if (iscntrl((unsigned char) *name)) return false;
name++;
}
return true;
}
edited Jan 3 at 21:46
answered Jan 3 at 21:22
chuxchux
84.8k874157
84.8k874157
Thanks a lot. I tried using a tmp string of a fixed size (buffer in your case) but I used strcpy function, plus gets... I like your way of handling data. I will try it out tommorow. Thanks a lot!
– nnidza
Jan 3 at 22:22
add a comment |
Thanks a lot. I tried using a tmp string of a fixed size (buffer in your case) but I used strcpy function, plus gets... I like your way of handling data. I will try it out tommorow. Thanks a lot!
– nnidza
Jan 3 at 22:22
Thanks a lot. I tried using a tmp string of a fixed size (buffer in your case) but I used strcpy function, plus gets... I like your way of handling data. I will try it out tommorow. Thanks a lot!
– nnidza
Jan 3 at 22:22
Thanks a lot. I tried using a tmp string of a fixed size (buffer in your case) but I used strcpy function, plus gets... I like your way of handling data. I will try it out tommorow. Thanks a lot!
– nnidza
Jan 3 at 22:22
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54029147%2fstructures-with-variable-members-size%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
3
You never initialize either pointer to point at valid, sufficient memory. Your
getscalls invoked undefined behavior– UnholySheep
Jan 3 at 20:14
2
Also, don't use
gets– UnholySheep
Jan 3 at 20:15
Soooo, I should do...!?
– nnidza
Jan 3 at 20:17
1
Either allocate sufficient memory and limit user input to not be more than what you have or do something like in stackoverflow.com/questions/16870485/…
– UnholySheep
Jan 3 at 20:23
I understand, i think. Using malloc to allocate the memory, adding function for collectiing chars from the input and removing unwanted characters... All have to be in one...
– nnidza
Jan 3 at 20:48