Currently I have set up an array to hold 50 packets created by the program. However I would like to change this array to use malloc instead along with the use of storing a maximum of 50 pieces of information just as the current array does.
Here's the current code used to set up the array used under int main
struct packet create[50];
int countpackets = 0;
And the array is incremented within another function within the code as so
int add(struct packet *create, int countpackets){
char inputDest[10],inputType[4],inputPort[2],inputData[50],inputSource[10];
if (countpackets == 50){
puts("Too many packets already entered.");
}else{
printf("\n\n");
int i = 0;
printf("\t Source - Must be 1024 or below >\t");
scanf("%s", inputSource);
create[countpackets].source = atoi(inputSource);
for (i = 0; i < strlen(inputSource); i++){
while(isdigit(inputSource[i])== 0 || create[countpackets].source > 1024){
printf("************************************************** \n");
puts("Invalid input, numbers only or number too big\n");
printf("\t please re-enter your Source >");
scanf("%s", inputSource); //rescans if it's a letter
create[countpackets].source = atoi(inputSource);
}
}
printf("\t Destination - Must be 1024 or below >\t");
scanf("%s", inputDest);
create[countpackets].destination = atoi(inputDest);
for (i = 0; i < strlen(inputDest); i++)
{
while(isdigit(inputDest[i])== 0 || create[countpackets].destination > 1024){
printf("************************************************** \n");
puts("Invalid input, numbers only or number too big\n");
printf("\t please re-enter your Destination >");
scanf("%s", inputDest); //rescans if it's a letter
create[countpackets].destination = atoi(inputDest);
}
}
printf("\t Type - Must be 10 or below >\t");
scanf("%s", inputType);
create[countpackets].type = atoi(inputType);
for (i = 0; i < strlen(inputType); i++){
while(isdigit(inputType[i])== 0 || create[countpackets].type > 10){
printf("************************************************** \n");
puts("Invalid input, numbers only or number too big \t \n");
printf("\t please re-enter your Type >");
scanf("%s", inputType); //rescans if it's a letter
create[countpackets].type = atoi(inputType);
}
}
printf("\t Port - Must be 1024 or below >\t");
scanf("%s", inputPort);
create[countpackets].port = atoi(inputPort);
for (i = 0; i < strlen(inputPort); i++)
{
while(isdigit(inputPort[i])== 0 || create[countpackets].port > 1024){
printf("************************************************** \n");
puts("Invalid input, numbers only or number too big \t \n");
printf("\t please re-enter your Type >");
scanf("%s", inputPort); //rescans if it's a letter
create[countpackets].port = atoi(inputPort);
}
}
printf("\t Data have less than 50 characters >\t");
scanf("%s", inputData);
for (i = 0; i < strlen(inputData); i++){
while(isdigit(inputData[i])== 0){ //checks if it's a letter
printf("************************************************** \n");
puts("Invalid input, numbers only or number too big \t \n");
printf("\t please re-enter your Type >");
scanf("%s", inputData); //rescans if it's a letter
}
strcpy(create[countpackets].data, inputData);
}
}
countpackets++;
return countpackets;
}
I'm pretty new to C and I do believe that is all the code I need to show, however if need be I will put up my full program. Any help would be much appreciated.
If you want to declare this...
struct packet create[50];
...with malloc, you'll have to do this...
struct packet *pCreate = malloc(50 * sizeof(struct packet));
You can use it the same.
create[0] = pCreate[0]; // First element
create[49] = pCreate[49]; // Last element
Related
I'm trying to work on a program to input a phone number and test if it is the right amount of digits in C, also checking if the first value is not 0 or 1. Scanf is not taking a value when I enter it and I do not understand why. If someone could please point out to me what the issue is it'd be much appreciated.
#include <stdio.h>
int main (void){
int number = 0;
int loop = 0;
while(loop == 0){
printf("Enter a phone number: ");
scanf(" %d ", &number);
printf("%d", number);
int firstDigit;
while(number >= 10){
firstDigit = number/10;
}
if((number/1000000) >= 1 && (number/1000000) < 10){
if(firstDigit == 1){
printf("Invalid central office code: 1");
}
else if(firstDigit == 0){
printf("Invalid central office code: 0");
}
else{
int firstThree = (number/10000);
int lastFour = (number%10000);
printf("%d - %d", firstThree, lastFour);
}
}
else if(number == 0){
printf("Exiting.");
loop = 1;
}
else{
if((number/1000000)>=10){
printf("Invalid phone number: too many digits");
}
else if((number/1000000)<1){
printf("Invalid phone number: too few digits");
}
}
}
return 0;
}
This:
while(number >= 10) {
firstDigit = number/10;
}
is an infinite loop, because you are not modifying number.
What you probably want to do is:
while(number >= 10) {
firstDigit = number/10;
number /= 10;
}
You should avoid scanf() to read input. Better use fgets(), and then sscanf() for parsing.
char input[1024]; // This should be large enough
if (!fgets(input, sizeof input, stdin)) {
printf("Input error\n");
return 1;
}
input[strcsnp(input, "\n")] = '\0'; // Because fgets reads \n so remove it
if (sscanf(input, "%d", &number) != 1) {
printf("Parsing error\n");
return 1;
}
// Use number...
Also, scanf() and sscanf() "ignore" the first 0s you type as part of the phone number, so your solution might not be correct. The best way to represent a phone number is either by storing it as a string (as mentioned in a comment), or by defining a phone number structure.
Int size in c is 4 bytes, which can hold values only -2,147,483,648 to 2,147,483,647.
It can't store all 10 digit values.
you can use long
long number = 0;
scanf("%ld", &number);
printf("%ld", number);
Im doing a hangman game as a school project but Im facing an issue:
do{
system("cls");
// Header of the game
printf("\n HANGMAN GAME\n\n\n");
// Present letters found
for (i=0; word[i]!='\0'; i++)
printf (" %c ", word_2[i]);
printf("\n");
// Present positions to the letters
for (i=0; word[i]!='\0'; i++)
printf("___ ");
printf("\n");
// ****PLAYER'S ANSWERS*****
// Read player's answers
printf("\n\n Whats your guess + <enter>: ");
scanf("%c", &letter);
scanf("%c", &c);
// Verify if the letter is in the word
found=0;
for(i=0; word[i]!='\0'; i++)
if (word[i] == letter){
word_2[i] = letter;
corrects++;
max_attemps--;
found = 1;
printf("\nWell done, %s. You have now %d attempts\n\n", name, max_attemps);
system("pause");
}
if(found == 0){
max_attemps--;
printf("\nOh no, %s. You have now %d attempts\n\n", name, max_attemps);
system("pause");
}
if (max_attemps <= 0 || corrects == lenght) {
end = 1;
}
} while (end == 0);
When I got a right letter that have two or more position in the word it takes from me two or more attempts because of the system("pause") when in fact just had to takes me one. But if I don't put the system("pause") the board will be cleared before I can see the message. Anyone knows what can I do to solve this? I'll be very grateful.
Check your found flag only after you have scanned the whole word:
// Verify if the letter is in the word
found=0;
for(i=0; word[i]!='\0'; i++)
if (word[i] == letter){
word_2[i] = letter;
corrects++;
max_attemps--;
found = 1;
// comment out
// printf("\nWell done, %s. You have now %d attempts\n\n", name, max_attemps);
// system("pause");
}
if(found == 1)
{
printf("\nWell done, %s. You have now %d attempts\n\n", name, max_attemps);
system("pause");
}
else{
max_attemps--;
printf("\nOh no, %s. You have now %d attempts\n\n", name, max_attemps);
system("pause");
}
if (max_attemps <= 0 || corrects == lenght) {
end = 1;
}
i am trying to get this program to repeat when prompted Y or N and i cant seem to get it to work right for some reason and this is the last thing i have left and im pretty sure the rest of the code is right i think all i need is it to repeat the whole program if the user enters a "Y" or just exits if the user enters "N"
int main(void)
{
// Constant and Variable Declarations
const int MPH_SPEED_MIN = 1;
const int MPH_SPEED_MAX = 100;
const int HOURS_TRAVLED_MIN = 1;
int mphSpeed = 1;
int hoursEntered = 0;
int distanceTraveled = 0;
int counterNum = 0;
int distanceNum = 0;
char ch = 'y';
// *** Input ***
do {
printf("What is the speed of the vehicle in MPH? ");
scanf("%d", &mphSpeed);
while ((mphSpeed < MPH_SPEED_MIN) || (mphSpeed > MPH_SPEED_MAX)) {
printf("\tThe speed entered must be between %d and %d inclusive
\n",MPH_SPEED_MIN, MPH_SPEED_MAX);
printf("\tPlease re-enter the speed of the vehicle in MPH: ");
scanf("%d", &mphSpeed);
}
printf("How many hours has it traveled? ");
scanf("%d", &hoursEntered);
while (hoursEntered < HOURS_TRAVLED_MIN) {
printf("\tThe hours traveled must be a positive number.\n");
printf("\tPlease re-enter the number of hours traveled: ");
scanf("%d", &hoursEntered);
}
printf("\n");
printf("Hour\tDistance Traveled\n");
distanceTraveled = hoursEntered * mphSpeed;
for (counterNum = 1; counterNum <= hoursEntered; counterNum++) {
distanceNum = distanceTraveled * counterNum;
printf("%d\t%d miles\n", counterNum, distanceNum);
}
printf("\n");
printf("Run the program again (Y/N)? ");
scanf("%c", &ch);
printf("\n");
} while (ch == 'Y' || ch == 'y');
; return 0;
When reading in with scanf(%c..., the statement very likely reads in a new line character left in the buffer from previous inputs. Read in a string instead, because %s ignores any leading white spaces (including such a new line character left in the buffer).
Try ...
char exitYN[2];
if (scanf("%1s",exitYN) != 1) {
exitYN[0]='N';
}
char ch = exitYN[0];
} while (ch == 'Y' || ch == 'y');
The one small yet, the most effective change that can be made here is adding a <space> before the %c while accepting the Y or N, i.e, scanf(" %c, &ch");
And I don't know if the following are errors while typing the code in StackOverflow, or are they originally errors in your code, but definitely are worth making changes:
Header file missing: #include<stdio.h>,
Unwanted and extra semicolon (;) before the return statement at the end,
missing closing bracket (}) at the end, after the return.
Here is the working code:
#include<stdio.h>
int main(void)
{
// Constant and Variable Declarations
const int MPH_SPEED_MIN = 1;
const int MPH_SPEED_MAX = 100;
const int HOURS_TRAVLED_MIN = 1;
int mphSpeed = 1;
int hoursEntered = 0;
int distanceTraveled = 0;
int counterNum = 0;
int distanceNum = 0;
char ch = 'y';
// *** Input ***
do {
printf("What is the speed of the vehicle in MPH? ");
scanf("%d", &mphSpeed);
while ((mphSpeed < MPH_SPEED_MIN) || (mphSpeed > MPH_SPEED_MAX)) {
printf("\tThe speed entered must be between %d and %d inclusive\n",MPH_SPEED_MIN, MPH_SPEED_MAX);
printf("\tPlease re-enter the speed of the vehicle in MPH: ");
scanf("%d", &mphSpeed);
}
printf("How many hours has it traveled? ");
scanf("%d", &hoursEntered);
while (hoursEntered < HOURS_TRAVLED_MIN) {
printf("\tThe hours traveled must be a positive number.\n");
printf("\tPlease re-enter the number of hours traveled: ");
scanf("%d", &hoursEntered);
}
printf("\n");
printf("Hour\tDistance Traveled\n");
distanceTraveled = hoursEntered * mphSpeed;
for (counterNum = 1; counterNum <= hoursEntered; counterNum++) {
distanceNum = distanceTraveled * counterNum;
printf("%d\t%d miles\n", counterNum, distanceNum);
}
printf("\n");
printf("Run the program again (Y/N)? ");
scanf(" %c", &ch);
printf("\n");
} while (ch == 'Y' || ch == 'y');
return 0;
}
I have also attached the output just in case you need to verify.
OUTPUT:
What is the speed of the vehicle in MPH? 12
How many hours has it traveled? 1
Hour Distance Traveled
1 12 miles
Run the program again (Y/N)? y
What is the speed of the vehicle in MPH? 6
How many hours has it traveled? 6
Hour Distance Traveled
1 36 miles
2 72 miles
3 108 miles
4 144 miles
5 180 miles
6 216 miles
Run the program again (Y/N)? n
I have a problem with a program that should split a phone number(ex. 1231231234) that user enters into three groups and display them like this (123)-123-1234. I'm not sure how to split this number and what to use in order to complete it. I didn't completed the code party but here's what i got.
#define SIZE 3
int main(void){
int option, j;
int phList = 0;
int phoneNum[SIZE];
printf("---=== Phone Numbers ===---\n");
while(1){
printf("\n");
printf("1. Display Phone List\n");
printf("2. Add a Number\n");
printf("0. Exit\n");
printf("\n");
printf("Please select from the above options: ");
scanf("%d", &option);
if(option == 0){
printf("Exiting Phone Number App. Good Bye!!!\n");
return 0;
}
if(option == 1){
printf("\n");
printf("Phone Numbers\n");
printf("==============\n");
for(j = 0; j < phList; j++){
printf("\n", phoneNum[j]);
}
}
if(option == 2){
if(phList < SIZE){
printf("\n");
printf("Add a Number\n");
printf("============\n");
scanf("%d", &phoneNum[phList]);
phList++;
} else {
printf("Add a Number\n");
printf("============\n");
printf("ERROR!!! Phone Number List is F$
}
}
}
return 0;
}
I would consider using fgets() to get the phone number as a string, rather than getting it as an integer. Then you can filter the input so that only the digits are kept, allowing users to enter parenthesis, spaces, or dashes as desired. Finally, sscanf() can be used to scan the filtered string into three strings for the area code, exchange number, and subscriber number. If you like, these strings can be converted to numbers by atoi() or strtol().
The OP seems to be assuming that the phone number follows the format of the North American Numbering Plan, but phone number formats may differ. The string representation is more flexible than an integer representation, making future modifications to the code easier.
Here is an example of how this might be done:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
void filter_num(char *str);
int main(void)
{
char buffer[1000];
char area_code[4];
char xch_num[4];
char sub_num[5];
printf("Enter phone number: ");
if (fgets(buffer, sizeof buffer, stdin) == NULL) {
fprintf(stderr, "Error in fgets\n");
exit(EXIT_FAILURE);
}
filter_num(buffer);
if (sscanf(buffer, "%3s%3s%4s", area_code, xch_num, sub_num) != 3) {
fprintf(stderr, "Phone number format error\n");
exit(EXIT_FAILURE);
}
printf("Phone number is: (%s) %s-%s\n",
area_code, xch_num, sub_num);
return 0;
}
void filter_num(char *str)
{
char *p = str;
while (*p != '\0') {
if (isdigit(*p)) {
*str++ = *p;
}
++p;
}
*str = '\0';
}
I will suggest defining a function to split the number and display that, Please have a look on this one, I have written it for you just now and works fine:
void DisplayNum(long long int PhNum)
{
printf("\n ");
for(int i=1; i<=10; ++i) // Since Phone Number Contains 10 digits
{
int digit= PhNum/(pow(10,10-i)); // Spliting digits
digit= digit%10;
if(i==1)
{
printf(" (");
}
if(i==4)
{
printf(")-");
}
if(i==7)
{
printf("-");
}
printf("%d",digit); // Displaying Digits
}
}
But make sure to use #include<math.h> at the beginning because i am using pow() function here. Then you can just pass each Phone Number in array to display to this function. The for-loop to display each Phone Number in array will be like :
for(j = 0; j < phList; j++){
DisplayNum(phoneNum[j]);
}
So I am trying to write a program that prompts the user to input how many data sets the user wishes to have, aka how many arrays there are going to be. It then prompts the user to input how many values will be in each data set and what the values are. Finally it gives the user a list of options to run on a desired data set.
When I run my code and select which data set I want to use, it seems to always come up with the last data set and doesn't seem to have all of the values in the set. I was just wondering if someone could let me know what I'm doing wrong or at the very least put me on the right track. I've gone through the code multiple times and can't figure it out.
#include <stdio.h>
int main()
{
unsigned short int num_sets, set_size, set_desired, command = 0;
printf("Enter the number of data sets you would like to store: ");
scanf(" %hu", &num_sets);
int i = 1, j, sets[1][num_sets], sum, a;
while(i <= num_sets)
{
j = 1;
printf("Enter the number of elements in data set %hu: ", i);
scanf(" %hu", &set_size);
printf("Enter the data for set %hu: ", i);
while(j < set_size)
{
scanf(" %d", &sets[i - 1][j - 1]);
j++;
}
i++;
}
printf("Which set would you like to use?: ");
scanf(" %hu", &set_desired);
while(set_desired > num_sets){
printf("There aren't that many data sets, try again: ");
scanf(" %hu", &set_desired);
}
printf("Set #%hu: %hu\n", num_sets, *sets[num_sets - 1]);
while(command != 7){
printf("Choose what you would like to do:\n");
printf("1. Find the minimum value.\n");
printf("2. Find the maximum value.\n");
printf("3. Calculate the sum of all the values.\n");
printf("4. Calculate the average of all the values.\n");
printf("5. Sort the values in ascending order.\n");
printf("6. Select a different data set.\n");
printf("7. Exit the program.\n");
scanf(" %hu", &command);
if(command == 1){
printf("You picked 1!");
}
if(command == 2){
printf("You picked 2!");
}
if(command == 3){
/*printf("You picked 3!");
for(a = 0; a < set_size; a++){
sum = sum + *sets[a];
}
printf("%d\n", sum);*/
printf("You picked 3!");
}
if(command == 4){
printf("You picked 4!");
}
if(command == 5){
printf("You picked 5!");
}
if(command == 6){
printf("You picked 6!");
}
if(command == 7){
break;
}
}
}
If you are trying to store values in different sets than you need to maintain the number of items in each set separately as you don't know how many elements are there is each set.
The design should be such that:
Set 1 : Number of Elements : Actual values in the array.(Here I am storing the number of items in the set as part of the same array. It will be the first element in each set)
The memory allocation can be done dynamically as you are giving the option to the user to set the number of items per set.
#include <stdio.h>
#include<stdlib.h>
int main()
{
unsigned short int num_sets, set_size, set_desired, command = 0;
printf("Enter the number of data sets you would like to store: \n");
scanf(" %hu", &num_sets);
int *sets[num_sets];
int i = 0, k=0,j,sum, a;
while(i < num_sets)
{
j = 1;
printf("Enter the number of elements in data set %hu: \n", i+1);
scanf(" %hu", &set_size);
sets[i] = (int *) malloc((sizeof(int)*set_size));
*sets[i] = set_size;
printf("Enter the values for set %hu\n", i+1);
while(j <= set_size)
{
scanf(" %d", &sets[i][j]);
j++;
}
i++;
}
printf("Which set would you like to use?: \n");
scanf(" %hu", &set_desired);
while(set_desired > num_sets){
printf("There aren't that many data sets, try again: \n");
scanf(" %hu", &set_desired);
}
for(k=1;k<=(*sets[set_desired-1]);k++)
{
printf("Set #%hu: %hu \n", set_desired, *(sets[set_desired-1] + k));
}
while(command != 7){
printf("Choose what you would like to do:\n");
printf("1. Find the minimum value.\n");
printf("2. Find the maximum value.\n");
printf("3. Calculate the sum of all the values.\n");
printf("4. Calculate the average of all the values.\n");
printf("5. Sort the values in ascending order.\n");
printf("6. Select a different data set.\n");
printf("7. Exit the program.\n");
scanf(" %hu", &command);
if(command == 1){
printf("You picked 1!");
}
if(command == 2){
printf("You picked 2!");
}
if(command == 3){
/*printf("You picked 3!");
* for(a = 0; a < set_size; a++){
* sum = sum + *sets[a];
* }
* printf("%d\n", sum);*/
printf("You picked 3!");
}
if(command == 4){
printf("You picked 4!");
}
if(command == 5){
printf("You picked 5!");
}
if(command == 6){
printf("You picked 6!");
}
if(command == 7){
break;
}
}
return 0;
}
You have undefined behaviour in your code. In this line:
int i = 1, j, sets[1][num_sets], sum, a;
you allocate enough space for one element in each of num_sets sets of data. This isn't really what you need. You probably want the num_sets as the first index, and you need a larger value for the other index.
You are likely to need to do dynamic memory allocation. Failing that, you'll need to set an upper bound (maybe 100) on the size of the arrays, and reject attempts to create bigger arrays. You'd then use:
enum { MAX_ARR_SIZE = 100 };
int sets[num_sets][MAX_ARR_SIZE];
for the variable. Your data entry loop already assumes this method of indexing. You probably need to keep a record of how many entries there are in each row somewhere, so as to avoid using uninitialized data.
int set_size[num_sets];