I cannot seem to output a string or an integer array correctly in C programming.
My issue, is that the strings are stored in the array, I just cannot get them OUT of the array and to the output.
When I manually enter the positions (like Array[0]), it properly outputs.
However, the final loop fails to output any of my array entries.
Why is this happening?
Thanks in advance for all replies!
Here is the code:
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include <string.h>
main (void)
{
int memory_start;
int memory_end;
int num_jobs;
printf("Enter the starting memory location to be used : ");
scanf("%d", &memory_start);
printf("\nEnter the ending memory location to be used : ");
scanf("%d", &memory_end);
printf("\nHow many jobs will be assigned to the memory locations? \n");
scanf("%d", &num_jobs);
int mem_size = memory_end - memory_start;
int mem_size_init = memory_end - memory_start;
char names[10][20];
int sizes[num_jobs];
int mem_st[10];
int mem_end[10];
int x;
int y;
int z;
int temp_size = 0;
int prev_temp_size;
char temp_name[20];
for(x=0; x<num_jobs; x++)
{
prev_temp_size = prev_temp_size + temp_size;
printf("\nEnter the size of the program (size > 0): ");
scanf("%d", &temp_size);
if( mem_size >= temp_size && temp_size > 0)
{
printf("\nEnter a program name (20 chars): %s", names[1]);
scanf("%s", &temp_name);
if(strlen(temp_name) <= 20)
{
strcpy(names[x], temp_name);
// names[x] = temp_name;
sizes[x] = temp_size;
mem_size = mem_size - temp_size;
mem_st[x] = prev_temp_size + memory_start;
mem_end[x] = temp_size + mem_st[x];
}
else
{
printf("\nProgram name is too long. Please re enter data.");
x--;
}
}
else
{
printf("\nMemory Size not supported (not enough space remaining).\nPlease re-enter data with a plausible memory request.");
printf("\nMemory size remaining: %d", mem_size);
x--;
}
}
printf("\nYour data is as follows: \n");
printf("\nYour initial memory size is: %d", mem_size_init);
printf("\nYour unused memory size is: %d", mem_size);
for(y=0; y<num_jobs; y++)
{
printf("Program: %s", names[y]);
printf("\n", names[y], " memory size is as follows: \n", "memory start: %d", mem_st[y], " memory end: %d", mem_end[y]);
}
}
Here is the corrected code:
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include <string.h>
main (void)
{
int memory_start;
int memory_end;
int num_jobs;
printf("Enter the starting memory location to be used : ");
scanf("%d", &memory_start);
printf("\nEnter the ending memory location to be used : ");
scanf("%d", &memory_end);
printf("\nHow many jobs will be assigned to the memory locations? ");
scanf("%d", &num_jobs);
int mem_size = memory_end - memory_start;
int mem_size_init = memory_end - memory_start;
char names[10][20];
int sizes[num_jobs];
int mem_st[10];
int mem_end[10];
int x;
int y;
int z;
int temp_size = 0;
int prev_temp_size;
char temp_name[20];
for(x=0; x<num_jobs; x++)
{
prev_temp_size = prev_temp_size + temp_size;
printf("\nEnter the size of the program (size > 0): ");
scanf("%d", &temp_size);
if( mem_size >= temp_size && temp_size > 0)
{
printf("\nEnter a program name (20 chars): ");
scanf("%s", temp_name);
getchar();
if(strlen(temp_name) <= 20)
{
strcpy(names[x], temp_name);
sizes[x] = temp_size;
mem_size = mem_size - temp_size;
mem_st[x] = prev_temp_size + memory_start;
mem_end[x] = temp_size + mem_st[x];
}
else
{
printf("\nProgram name is too long. Please re enter data.");
x--;
}
}
else
{
printf("\nMemory Size not supported (not enough space remaining).\nPlease re-enter data with a plausible memory request.");
printf("\nMemory size remaining: %d", mem_size);
x--;
}
}
printf("\nYour data is as follows: \n");
printf("\nYour initial memory size is: %d", mem_size_init);
printf("\nYour unused memory size is: %d\n", mem_size);
for(y=0; y<num_jobs; y++)
{
printf("\nProgram: %s\n", names[y]);
printf("\nmemory size is as follows:\nmemory start: %d memory end: %d\n", mem_st[y], mem_end[y]);
}
}
Apart from changes in formatting the output, major changes are:
Removed the & in scanf("%s", &temp_name); because, the name of an array already returns a reference to its first element.
Added a getchar(); after scanf("%s", temp_name); because after reading in a string an extra \n remains in the stream, which causes the next scanf to fail.
This:
printf("\n", names[y], " memory size is as follows: \n", "memory start: %d", mem_st[y], " memory end: %d", mem_end[y]);
is not how a format specifier is prepared, all variables need to be placed at the end, after a single format specifier string.
The last loop is the issue.
for(y=0; y<num_jobs; y++)
{
printf("Program: %s", names[y]);
printf("\n memory size is as follows: ");
printf("\n memory start: %d memory end: %d", mem_st[y], mem_end[y]);
}
In C, the variables are given at the end of the printf. Also you are printing names two times, which i guess you don't want.
Related
The idea is to restock certain product by getting stdin from user and compare it to string value of the array - for the product names
My function code
void free_restock(){
print_inventory();
printf("What do u want to restock: ");
char *temp_string_for_name;
scanf("%s", &temp_string_for_name);
printf("How much do u want to restock: ");
int temp_val_for_restock = 0;
scanf("%d", &temp_val_for_restock);
for(int i = 0; (strlen(INVENTORY_NAMES_ARRAY[i])) != 0; i++){
if(strcmp(temp_string_for_name, INVENTORY_NAMES_ARRAY[i]) == 0){
INVENTORY_AMOUNT_ARRAY[i] += temp_val_for_restock;
printf("Now u have %d from %s\n", INVENTORY_AMOUNT_ARRAY[i], INVENTORY_NAMES_ARRAY[i]);
break;
}
printf("%d", i);
}
}
Arrays initialization
#define MAX_SIZE_OF_ARRAYS 100
static int INVENTORY_AMOUNT_ARRAY[MAX_SIZE_OF_ARRAYS];
static char INVENTORY_NAMES_ARRAY[MAX_SIZE_OF_ARRAYS][MAX_SIZE_OF_ARRAYS];
My gdb error:
0x00007ffff7e01ecb in ?? () from /usr/lib/libc.so.6
I am trying to access different elements in my dynamic struct array however I can't seem to access any other element in the array besides the first.
C file
#include <stdio.h>
#include <stdlib.h>
#include "tuples.h"
void createTuple();
int main() {
createTuple();
return 0;
}
void createTuple(){
int numOfTup;
printf("How many tuples would you like to create:\n");
scanf(" %d", &numOfTup);
tuple_t *tuples;
tuples = malloc(numOfTup * sizeof(char) * sizeof(int) * 3);
if (tuples == NULL){
printf("Memory allocation failed");
exit(EXIT_FAILURE);
}
for (int j = 0; j < numOfTup; ++j) {
printf("Enter an identifier for the Tuple: \n");
scanf(" %c", &tuples[j].identifier);
printf("TUPLE: %c\n",tuples[j].identifier);
for (int i = 0; i < 4; ++i) {
printf("Enter the value for the tuple (C:I:I:I)\n");
if (i == 0) {
scanf(" %c", &tuples[j].val0);
} else if (i == 1) {
scanf(" %d", &tuples[j].val1);
} else if (i == 2) {
scanf(" %d", &tuples[j].val2);
} else if (i == 3) {
scanf(" %d", &tuples[j].val3);
}
}
}
}
Header file for the struct
#ifndef TASK2_TUPLES_H
#define TASK2_TUPLES_H
struct tuple{
char identifier[100];
char val0;
int val1;
int val2;
int val3;
};
typedef struct tuple tuple_t;
#endif //TASK2_TUPLES_H
I can't seem to access the struct at tuples[j] because whenever I try to run it it only saves the first set of elements.
Also whenever inputting the identifier the compiler skips the loop and does not allow me to enter any elements into the struct.
Thanks.
For starters, the statement:
tuples = malloc(numOfTup * sizeof(char) * sizeof(int) * 3);
//always ==1 why? why?
Should look more like:
tuples = malloc(numOfTup * sizeof(*tuples));
and:
scanf(" %c", &tuples[j].identifier);//wrong format specifier for string
^^^ ^ //and address of ( & ) operator not needed for string.
Should be:
scanf("%s", tuples[j].identifier);
^^ ^
There are several issues with your code:
You allocate nowhere near enough memory. If your tuple identifier is 100 chars, you should allocate at least 101 * sizeof(char) + 3*sizeof(int) bytes of memory. In practice, this might not suffice because the compiler might pad the struct to better align with memory. Thus, the real size might be greater. The safe thing to do is to allocate sizeof(tuple_t) bytes
Your scanf function to read the identifier reads a char, not a string. use %s to read string. Also, scanf expects pointers to already allocated objects of the type specified by their corresponding format specifier, in our case, %s is a string, so the type should be char *. Thus, the parameter should be tuples[j].identifier, rather than &tuples[j].identifier
Overall:
#include <stdio.h>
#include <stdlib.h>
#include "tuples.h"
void createTuple();
int main() {
createTuple();
return 0;
}
void createTuple(){
int numOfTup;
printf("How many tuples would you like to create:\n");
scanf(" %d", &numOfTup);
tuple_t *tuples;
tuples = malloc(numOfTup * sizeof(tuple_t));
if (tuples == NULL){
printf("Memory allocation failed");
exit(EXIT_FAILURE);
}
for (int j = 0; j < numOfTup; ++j) {
printf("Enter an identifier for the Tuple: \n");
scanf("%s", tuples[j].identifier);
printf("TUPLE: %s\n",tuples[j].identifier);
for (int i = 0; i < 4; ++i) {
printf("Enter the value for the tuple (C:I:I:I)\n");
if (i == 0) {
scanf(" %c", &tuples[j].val0);
} else if (i == 1) {
scanf(" %d", &tuples[j].val1);
} else if (i == 2) {
scanf(" %d", &tuples[j].val2);
} else if (i == 3) {
scanf(" %d", &tuples[j].val3);
}
}
}
}
I wrote a program in C which takes as an input a value and an ordered Array of integers and performs a ternary search to find the value(if it exists) inside the Array.
I have seen all the possible problems with the usage of scanf and the related topics here in Stackoverflow.
I have noticed that there is a difference if I call the 2 scanf functions in reverse order.
If I use the code as it is below. First read the value and after the array from the user, the program and scanf functions as expected.
printf("Enter the value to be searched in the Array: ");
int k;
scanf(" %d", &k);
printf("Type elements of A(sorted) separated by spaces (type 'end' to stop): ");
i = 0;
while(scanf("%d", &A[i]) == 1) {
i++;
}//while
Although if I use the scanf inputs in the reverse order the second scanf never stops to get user input and read values left in the buffer.
printf("Type elements of A(sorted) separated by spaces (type 'end' to stop): ");
i = 0;
while(scanf("%d", &A[i]) == 1) {
i++;
}//while
printf("Enter the value to be searched in the Array: ");
int k;
scanf(" %d", &k);
I cannot understand what is the difference in the calling order.
I have tried the solutions mentioned in the other threads but none worked.
Just as a reference here is the whole code(working as expected):
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int ternarySearch(int A[], int l, int r, int k){
int i;
int first,second;
if(l>r){
return -1;
}
i= (r - l)/3;
if(i==0){
i++;
}
first = i+l-1;
second = i*2+l-1;
if(A[first]==k){
return first;
}
else if(A[first]>k){
ternarySearch(A, l, first-1, k);
}
else
{
if(A[second]==k)
return second;
else
if(A[second]>k)
ternarySearch(A, first+1,second-1, k);
else
ternarySearch(A, second+1,r, k);
}
}
int main(){
const int maxarraylen = 1000;
int i;
int n;
int A[maxarraylen];
char string[250];
printf("Enter the value to be searched in the Array: ");
int k;
scanf(" %d", &k);
printf("Type elements of A(sorted) separated by spaces (type 'end' to stop): ");
i = 0;
while(scanf("%d", &A[i]) == 1) {
i++;
}//while
n=i-1;
//We assume the array is sorted otherwise we can use any sorting algorithm e.g. code from task1
scanf(" %d", &k);
int result;
result=ternarySearch(A, 0, n, k);
if(result==-1){
printf("The value was not found in the Array.\n");
}
else{
printf("The value was found in position no. %d.\n", result);
}
return 0;
}
Your problem is that you are not 'stepping over' your end input.
We can see this by doing an experiment using the following program:
#include <stdio.h>
#include <stdlib.h>
void main(void) {
FILE *f;
long f_pos;
int ret;
int i;
int data[5];
int data_last;
int search;
f = fopen("./input.txt", "r");
if (f == NULL) {
perror("fopen()");
return;
}
/* read in the values for the array */
data_last = -1;
for (i = 0; i < 5; i++) {
ret = fscanf(f, "%d", &(data[i]));
printf("fscanf(data[%d]): ret: %d\n", i, ret);
f_pos = ftell(f);
printf("ftell(): %ld\n", f_pos);
if (ret != 1) {
break;
}
data_last = i;
}
/* check that we read in at least one value */
if (data_last == -1) {
printf("no input data!\n");
return;
}
/* insert 'fix' here */
/* pre-load the 'search' with known garbage */
search = 987;
/* now read in the search value */
ret = fscanf(f, "%d", &search);
printf("fscanf(search): ret: %d\n", ret);
f_pos = ftell(f);
printf("ftell(): %ld\n", f_pos);
/* print out our info */
for (i = 0; i <= data_last; i++) {
printf("data[%d]: %d\n", i, data[i]);
}
printf("search for: %d\n", search);
return;
}
With the following data in input.txt:
123
456
end
456
The output is as follows:
fscanf(data[0]): ret: 1
ftell(): 3
fscanf(data[1]): ret: 1
ftell(): 7
fscanf(data[2]): ret: 0
ftell(): 8
fscanf(search): ret: 0
ftell(): 8
data[0]: 123
data[1]: 456
search for: 987
ftell() tells us where the file's cursor is, and in this case we can see that it is at byte 8... the e of the input line end.
It doesn't get past it, and thus the next attempt to read a number (%d) will fail too!
It's also a good idea to check the return values! We can see that the fscanf(&search) call has failed to read a number!
The solution is to insert this snippet just after we check that we recieved array values:
/* this is the 'fix' */
ret = fscanf(f, "end");
printf("fscanf(end): ret: %d\n", ret);
f_pos = ftell(f);
printf("ftell(): %ld\n", f_pos);
I'm having trouble storing the size of each array the user inputs. I need to do this so that I can run different calculations on each set. This is what I'm trying to do now, but it keeps throwing a segmentation fault, and I don't know what I'm doing wrong. The other thing I thought of doing was essentially make one more memory spot with malloc and just store the sizes in another array at the end of the data set arrays. Anyway, here's the code that is giving me a segmentation fault.
int construct_data_sets(int *sets[], int count) {
int set_size;
int j;
j = 0;
printf("Enter the number of elements in data set %d: ", count+1);
scanf(" %d", &set_size);
sets[count] = (int*)malloc((sizeof(int) * set_size));
if (sets[count] == NULL){
printf("Malloc failed!\n");
}
printf("Enter the data for set %d: ", count+1);
while ((j + 1) <= set_size)
{
scanf(" %d", &sets[count][j]);
j++;
}
return set_size;
}
And here's the main, I think the segmentation fault gets thrown when I call construct_data_sets().
int main() {
int command = 0, data_set, set_desired, array_size;
int number = prompt_num_sets();
int *sets[number], i = 0, *sizes[number];
while (i < number)
{
array_size = construct_data_sets(sets, i);
*sizes[i] = array_size;
i++;
}
//printf("The size of the 3rd data set is %d", *sizes[3]);
printf("Data at [data_set][1] = %d\n", sets[data_set-1][1]);
set_desired = select_data_set(number);
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(" %d", &command);
if (command == 7) {
exit_program();
} else if (command == 6) {
change_term(number, sets);
}
printf("====================================\n");
}
}
Any weird printf statements you may see are just me trying to make sure things are doing what they're supposed to. Let me know if you need more information from me. Thanks.
You have multiple bugs in your code and several stylistic issues. Have you tried running the code in the debugger to see exactly where things are crashing? Have you tried narrowing the code down to a smaller problem?
Your sizes array should have an element type of int instead of int *. You are dereferencing uninitialized memory since you have not allocated anything for the pointers. Your data_set variable is also uninitialized so the array access into sets is also undefined.
You should initialize all of your variables immediately upon definition. Also I would change your code to declare only one variable per statement. The current code is quite difficult to read.
I would also change your initial while loop into a for loop.
Here's a working version that doesn't crash; although, since you haven't included all of the code, I don't know if there are other parts that are broken. I've also had to remove the references to the undefined functions:
#include <stdio.h>
#include <stdlib.h>
int construct_data_sets(int *sets[], int count) {
int set_size;
int j;
printf("Enter the number of elements in data set %d: ", count+1);
scanf(" %d", &set_size);
sets[count] = (int *) malloc((sizeof(int) * set_size));
if (sets[count] == NULL) {
fprintf(stderr, "Malloc failed!\n");
exit(-1);
}
printf("Enter the data for set %d: ", count+1);
for (j = 0; j < set_size; ++j) {
scanf(" %d", &sets[count][j]);
}
return set_size;
}
int main(int argc, char *argv[]) {
int command = 0;
int number = 1;
int *sets[number], i, sizes[number];
for (i = 0; i < number; ++i) {
sizes[i] = construct_data_sets(sets, i);
}
printf("Data at [0][1] = %d\n", sets[0][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(" %d", &command);
if (command == 7) {
return 0;
} else if (command == 6) {
return 0;
}
printf("====================================\n");
}
return 0;
}
Ok so I got this thing going here.
I keep getting a few errors.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <cstdio>
//functions called
int get_lmt();
int get_total_trash();
void print_output(int, int);
//why is it void?
int main(void)
{
char hauler[100];
int t_trash=0, lmt=0;
printf("Hello \n What is your name: ");
fflush(stdin);
scanf("%s", &hauler);
t_trash = get_total_trash();
lmt = get_lmt();
printf("Name: %s\n", &hauler);
print_output(lmt, t_trash);
system("pause");
return 0;
}
int get_total_trash()
{
char yn = 'y';
int t_trash = 0, trash=0;
while (yn != 'n')
{
printf("What is your trash: ");
fflush(stdin);
scanf("%i", &trash);
t_trash = trash + t_trash;
printf("Do you have more trash tons? (y or n): ");
fflush(stdin);
scanf("%c", &yn);
}
return t_trash;
}
int get_lmt()
{
int lmt = 0;
printf("What was last months trash: ");
fflush(stdin);
scanf("%i", &lmt);
return lmt;
}
void print_output(int lmt, int t_trash)
{
float rate = 350.00, charge;
int sum=0, total=0;
if (lmt > t_trash)
{
printf("Total trash tons: %i\n", &t_trash);
printf("Last month's trash: %i\n", &lmt);
printf("Rate: $ %.2f\n", &rate);
}
else
{
printf("What is your tonnage rate: ");
fflush(stdin);
scanf("%.2f\n", &charge);
sum = t_trash - lmt;
total = sum * charge;
rate = rate + total;
printf("Total trash tons: %i\n", &t_trash);
printf("Last month's trash: %i\n", &lmt);
printf("Rate: $ %.2f\n", &rate);
}
}
Now what it should be doing is, The main should be calling the functions on screen as needed.
Now i did all of this with cout cin and it works fine no problems. But when I run this (this is modified to the printf and scanf) it says:
OK UPDATE: Got a ton of it to work. Just one more thing and I should be good. The outcome will not go as expected.
Instead of an output of
last months trash: 100 (asked at the end of the loop)
trash tonnage: 50 (accumulated in the loop)
rate: 350.00 (float variable)
(this is if last month trash was > this month.)
I get just bad numbers all around. It makes no mathematical sense.
Other then that it works fine.
Does the code the the last function look wrong to you guys?
Lots of problems with this code. Lots of them.
1) print_output defintiion takes in a char[100] (char*), print_output declatation takes a char
2) When you pass hauler into print_output, you are passing in hauler[100] (a char, and one pass the end of the array to boot)
3) printf("Name: %s\n", &hauler); hauler is of type char[100] (char*), so &hauler is char**.
there is probably more.