reading hex from text file and split it in c program - c

I am reading from text file hex, but I want to split it to two digits?
#include <studio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
void main() {
char hexa[100];
FILE *fp = fopen ("data2.txt", "r+");
fscanf(fp, "%s", hexa);
printf("\n first data = %s \n", hexa);
printf("\n first digit= %s \n", hexa[1]);
printf("\n second digit= %s \n", hexa[2]);
fclose(fp);
}
I read from the file successfully, but the result is:
first data = 16
segmentation fault

hexa[1] and hexa[2] are characters, but you're printing them as though they were strings, that is, character arrays. Since they're in the range 0-255, and this range of memory is inaccessible, you get a crash.
Do this:
printf("\n first digit= %c \n", hexa[1]);
and so on.

I suppose you may want to use:
printf("\n first data = %s \n", hexa);
printf("\n first digit= %c \n", hexa[1]);
printf("\n second digit= %c \n", hexa[2]);
hexa decays to a pointer to char, and hexa[1] is a char. The arguments corresponding to "%s" expected by printf() are char *s, so passing hexa[1] causes segmentation fault. To print a single character, you should use "%c" specifier.

Related

C: Can not access the struct data in main after enter data from function

I am new to the C program, I am using a struct with array variables to contain my data set. However, after I enter one set of data to the struct and want to print the data set out on the main function it shows me something unknown word or empty.SO, how can I get access to the data in the main or in other functions from the struct? Did I do something wrong? Here is the code. Any suggestions on that? Thanks in advance!
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include<ctype.h>
struct Team{
char tem[40];
char proj[40];
char leader[40];
char mem1[40];
char mem2[40];
char mem3[40];
};
void project_team(struct Team arr[5]){
char str[100];
printf("Enter> ");
scanf("%[^\n]s",str); //%[^\n]s can input string including space
sscanf( str, "%s %s %s %s %s %s",arr[0].tem,arr[0].proj,arr[0].leader,arr[0].mem1,arr[0].mem2,arr[0].mem3); //conver user input string to words and store in struct variable separately
printf("show: %s %s %s %s %s %s \n",arr[0].tem,arr[0].proj,arr[0].leader,arr[0].mem1,arr[0].mem2,arr[0].mem3);
}
int main(int argc, char *argv[]){
struct Team arr[5];
project_team( &arr[5] );
printf("showthis: %s %s %s %s %s %s \n",arr[0].tem,arr[0].proj,arr[0].leader,arr[0].mem1,arr[0].mem2,arr[0].mem3);
return 0;
}
After I Enter:
Enter> TeamA ProjectA Amy Kelvin Fanny Jacky
It Display:
showthis: /usr/lib/dyld � �bx�� *
What I expect to show:
showthis: TeamA ProjectA Amy Kelvin Fanny Jacky
In this call:
project_team( &arr[5] );
you are passing the address of memory after the last element of the array.
You need to write:
project_team( arr );
In this call of scanf:
scanf("%[^\n]s",str);
remove the character 's' from the format string:
scanf(" %[^\n]",str);
It would be even more safer to write:
scanf(" %99[^\n]",str);
Pay attention to that the structure has 6 character arrays with 40 characters in each array. It is evident that 6 * 40 much greater than 100.

Don't have right output while comparing chars

#include <stdio.h>
#include <stdlib.h>
struct patients{
char last_name[15];
int passport_number;
char disease[30];
char doctors_last_name[15];
};
int main (){
int n,i;
char enter_doctors_last_name [15];
struct patients mas_struct[3]={{"Ivanov",5457401,"COVID-18","Davis"},{"Petrov",2864228,"COVID-19","Davis"},{"Petrova",63863380,"COVID-19","Dixon"}};
printf("\nPatients:");
printf("\n Last name | Passport number | \tDisease | Doctor's last name ");
for (i=0;i<3;i++)
printf("\n %s \t%d \t%s \t%s",mas_struct[i].last_name,mas_struct[i].passport_number,mas_struct[i].disease,mas_struct[i].doctors_last_name);
printf("\n");
printf("\nEnter doctor's last name:");
scanf("%s", enter_doctors_last_name);
printf("\nPatients:");
for (i=0;i<3;i++)
if(mas_struct[i].doctors_last_name == enter_doctors_last_name)
printf("\n %s \t%d \t%s \t%s",mas_struct[i].last_name,mas_struct[i].passport_number,mas_struct[i].disease,mas_struct[i].doctors_last_name);
return 0;
}
Got trouble in comparing chars, it doesn't work and I can't come up with the right words for googling it.
In the last lines when I type "Davis" or "Dixon" for enter_doctors_last_name
Output is just Patients
I also tried to use gets function
You can't compare strings with == operator, use strcmp instead:
if (!strcmp(mas_struct[i].doctors_last_name,enter_doctors_last_name)){/*...*/}
scanf with "%s" specifier is very unsafe use "%14s" instead, the -1 character is to reserve space for the null-terminator.
If you need names with more than 1 word you should use "%14[^\n]", reads everything until the newline character is found.
You should use strcmp() function for comparing strings.

How to fill gaps between Text in C Language

I have a text and i want to fill it with data in C
char arr[100]="Ahmed %s salah %s is %d";
i want to add data instead of %s and %d
to be
arr="Ahmed Elsayed salah Elsenbawy is 16";
just use sprintf or snprintf.
Using char * causes buffer overflow in this case.
#include <stdio.h>
#include <string.h>
int main ()
{
char arr[100]="Ahmed %s salah %s is %d";
char temp[100];
// fill the temp buffer
sprintf(temp,arr, "Elsayed","Elsenbawy",16);
//then copy
strncpy(arr,temp,100);
printf("%s\n", arr);
return 0;
}

qsort gives strange characters in the output

I want to sort employee data based on names. The sorting function works but provides strange characters in the output??
The last printf statement is the culprit I guess (bottom of the code)
If someone could help, that would be appreciated.
Thanks
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct
{
char name[25];
char firstname[25];
char job;
float hrs;
float rate;
} employee;
int main()
{
FILE *fp = fopen("employee.dat", "r");
employee staff[30];
int i = 0;
if (fp == NULL){
printf("not working\n");
exit(1);
}
fscanf(fp, "%s %s %c %f %f", staff[i].name, staff[i].firstname, &staff[i].job, &staff[i].hrs, &staff[i].rate);
while(!feof(fp))
{
printf("%s %s %c %4.1f %4.1f \n", staff[i].name, staff[i].firstname, staff[i].job, staff[i].hrs, staff[i].rate);
i++;
fscanf(fp, "%s %s %c %f %f", staff[i].name, staff[i].firstname, &staff[i].job, &staff[i].hrs, &staff[i].rate);
}
fclose(fp);
// qsort struct function for comparing names
int struct_cmp_by_name(const void *a, const void *b)
{
employee *ia = (employee *)a;
employee *ib = (employee *)b;
return strcmp(ia->name, ib->name);
}
int structs_len;
structs_len = sizeof(staff) / sizeof(employee);
// sort on names
qsort(staff, structs_len, sizeof(employee), struct_cmp_by_name);
//output with strange charaters???
for(i=0; i<structs_len; i++){
printf("%s %s %c %4.1f %4.1f \n", staff[i].name, staff[i].firstname, staff[i].job, staff[i].hrs, staff[i].rate);
}
return(0);
}
I am expecting a regular output of the printf statement.
The first printf works fine but the one after the qsort provides strange characters instead??
The most likely culprit of your problem is that you sort the whole array, even when maybe not all elements are initialized.
If the file contains less than the 30 elements you have for the array, parts of the array will be uninitialized with indeterminate contents (which may sometimes seem random or like "garbage"). You should not use those when sorting, only sort the data you actually have read from the file.
You have the number of valid and initialized elements in the array in the variable i which you should use instead:
qsort(staff, i, sizeof(employee), struct_cmp_by_name);
You have the same problem when printing the data: You print the whole array, including the uninitialized parts.
I suggest you create a new variable for the number of valid elements, suitable named, instead of the generic i that you now use.

Segfault - sscanf to arrays in C

I just need an extra set of eyes to help me find out why this code is segfaulting.
//------------------------Preprocessor Instructions. ------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#define NUMBER 128 //Maxmimum number of items/lines in file.
#define BUFFER 120 //Buffer length (For user input)
#define LENGTH 32 //Maximum length of lines in file.
//------------------------Global stuff. ---------------------------------------------
int iterations=0; //Will count number of times the calculation function is called.
int weight[NUMBER];
int value[NUMBER];
char object[NUMBER][LENGTH];
//------------------------Function Definitions. -----------------------------------------
void printarr();
//------------------------Printarr -- Array printing function. --------------------------
void printarr()
{
int i,j;
printf("\n");
printf("Weight \t Value \t Object \n");
for(i=0;i<4;i++){
printf("%d \t %d \t %s \n", weight[i], value[i], &object[i][0]);
}
}
//------------------------Main. ---------------------------------------------------------
int main(int argc, char **argv)
{
FILE *fp; //File pointer.
char buffer[BUFFER]; //Temporary storage
int result; //sscanf return value.
int capacity; //User input.
int i,j=0; //Loop counters.
//Command Line Argument Parsing: Assigns input value to capacity.
if (argc != 2){
printf("Usage: %s number. Max 1024. \n",argv[0]); //Usage: *program* *num*
return(1);
}
if (1 != sscanf(argv[1],"%d",&capacity)){
printf("Usage: %s number. Max 1024. \n",argv[0]);
return(1);
}
//File reading.
fp=fopen("knapsack.data","r");
if(NULL==fp){
printf("Error opening file. \n");
exit(0);
}
//Write to arrays.
while(NULL != fgets(buffer, BUFFER, fp)){
result=sscanf(buffer, "%d %d %s", &weight[i], &value[i], &object[i][0]);
i++;
}
//Print the arrays.
printarr();
fclose(fp);
}
According to GDB it segfaults when it hits the sscanf statement. But as far as I can tell there's nothing wrong with the way I'm accessing the locations... clearly I'm mistaken. Any help would be appreciated.
Edit: I was half right, fix this line:
result=sscanf(buffer, "%d %d %s", &weight[i], &value[i], &object[i][0]);
to look like this:
result=sscanf(buffer, "%d %d %s", &weight[i], &value[i], object[i]);
You are reading in a whole string, so you need to write to the c string location, in this case, object[i]. Also, init i for best practice (although gcc does init ints to zero if uninitialized, try it yourself and see).
Edit: Ignore the downvote, I am correct but I did make an error in forgetting to remove your second index, you can access a c string 2d array with object[i] or &object[i][0], both work. object[i] for accessing an entire string looks cleaner to me than using &object[i][0].

Resources