I am writing a below Pro*C program and I am getting core dump error, could someone please help me what I am doing wrong. I am new to C
int main(int argc,char *argv[])
{
char inputpath1[300]="";
char inputpath2[300]="";
gets(inputpath1);
gets(inputpath2);
ExtractCmpFiles(inputpath1,inputpath2); //contains fullpath with file
return 0;
}
void ExtractCmpFiles(char *inputpath1,char *inputpath2)
{
int i=0;
char *strings[2];
strings[0]=malloc(sizeof(inputpath1)+1);
strcpy(strings[0],inputpath1);
strings[1]=malloc(sizeof(inputpath2)+1);
strcpy(strings[1],inputpath2);
printf("Your files are:\n%s\n%s\n",strings[0],strings[1]);//i am getting output here
char **holder='\0';
char ioarea[4096];
for(i=0;i<2;i++)
{
inFile=fopen(strings[i],"r");
if(!inFile)
{
fprintf(stderr,": Open failure for output file:");
fprintf(stderr,strings[i]);
fprintf(stderr,"\n");
}
holder=&strings[i];
holder=strrchr(strings[i],'/'); //checking the address of '/' to get only filename
holder++; //incrementing pointer
printf("your holder is: %s\n",*holder);
if(strncmp(holder,"bills",5)==0) //checking value from the pointer address is "bills" or not
{
//do as you wish
}
}
}
output:
/your/path/bills.cmp
/your/path/bill.cmp
Thank you all. I have modified the function as per suggestions, but still I am getting core dump error
Adding modified function:
void ExtractCmpFiles(char *inputpath1,char *inputpath2)
{
char *strings[2];
strings[0]=(char*)malloc(strlen(*inputpath1)+1);
strcpy(strings[0],inputpath1);
strings[1]=(char*)malloc(strlen(*inputpath2)+1);
strcpy(strings[1],inputpath2);
printf("Your files are:\n%s\n%s\n",strings[0],strings[1]);
char *holder=NULL;
char ioarea[4096];
int i=0;
for(i=0;i<2;i++)
{
inFile=fopen(strings[i],"r");
if(!inFile)
{
fprintf(stderr,": Open failure for output file:");
fprintf(stderr,strings[i]);
fprintf(stderr,"\n");
}
holder=strings[i];
holder=strrchr(strings[i],'/');
printf("i=%d --- %s\n",i,strings[i]); //when i=0 it is giving output then it is giving coredump
printf("your holder1 is: %s\n",holder);
holder++;
printf("your holder2 is: %s\n",holder);
if(strncmp(holder,"custbills",9)==0)
{
//do something
}
else
{
//do something
}
fclose(inFile);
}
The variable holder is a pointer to a pointer to char, and you assign to it the result of strrchr, a function that returns a pointer to char.
That will make holder no longer point to the array entry, so when you do holder++ it points somewhere else completely which leads to undefined behavior when you dereference holder. You then continue to pass holder to strncmp which again will give you undefined behavior.
The holder variable is not a character either, so you should not initialize it as one. If you want to initialize it you should initialize it to point to NULL.
The things mentioned above should make the compiler shout warnings at you.
Also, as noted in a comment by Cool Guy, if you want to get the length of a string you should use strlen. When you use sizeof you get the size of the pointer and not what it points to.
strings[0]=(char*)malloc(strlen(inputpath1));
strings[1]=(char*)malloc(strlen(inputpath2));
...
char *holder=NULL;
...
fclose(inFile);
Related
I have a program that I have not written. It is supposed to remove white spaces from the string, and turn it into a camel case format. For example:
Input: Hello World!
Supposed to give: helloWorld!
Now I have a couple of questions about this program.
#include <stdio.h>
#include <ctype.h>
char *convert(char *f) {
char *save = f;
char *output = f;
int in_a_word = 1;
while(isspace(*f)) f++;
for(; *f; f++) {
if(isspace(*f)) in_a_word = 0;
else
{
if(in_a_word) {
*output= tolower(*f);
}
else {
*output = toupper(*f);
}
in_a_word = 1;
output++;
}
*output= '\0';
}
return save;
}
int main(void) {
char str[] = " Hello World\t";
printf("Modified: -->%s<---\n", convert(str));
getchar();
}
My questions:
char *save = f;
char *output = f;
If I understand correctly, both of them are supposed to point to f. I have written an experiment program:
int main(void) {
char *s = " Hello";
char *ment = s;
printf("Original:\n-->%s, %p<---\n-->%s, %p<---\n\n", s,s,ment,ment);
while(isspace(*s)) s++;
printf("Modified:\n-->%s, %p<---\n-->%s, %p<---", s,s,ment,ment);
getchar();
}
In this program I have saved the address of s in ment. When I use the first printf, it shows that they are completely equal, and they point to the same location. I make a little modification on s. This removes all the space from s, but ment stayed the same. Even their location changed.
Going back to the original program. In the convert function we are returning save, but it has not been modified. So my question is: can anyone explain why we are returning save? And/or which source material should I refer to. I read a couple of books on pointers, but none has mentioned this.
In the convert function we are returning save, but it has not been modified. So my question is: can anyone explain why we are returning save?
save is to store the original location of the string. Note that output pointer is modified within the function:
output++; // output pointer has been modified to point to next character
So you can't return output itself - you want to return the original location of the string.
In other words, there are distinct purposes of the two pointers in that function:
output is to modify the string content (this pointer changes throughout the function)
save is to store the original string location (this pointer isn't changed within the function) and for returning it to the calling function
I am trying to take multiple string input in an array of char pointer,the no. of strings is also taken from user. I have written following code but it does not work properly, Please if somebody could help me to fix it? It is taking some random no. of inputs not given by user.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
int l,j,i=0;
int p;// scanning no of strings user wants to input
scanf("%d",&p);
char c;
char **ptr=(char**)malloc(sizeof(char*)*p);// array of char pointer
if(ptr!=NULL)
{
for(i=0;i<p;i++)//loop for p no of strings
{
j=0;
ptr[i]=(char*)malloc(200*sizeof(char));//allocating memory to pointer to char array
if(ptr[i]!=NULL)//string input procedure
{
while(1)
{
c=getchar();
if(c==EOF||c=='\n')
{
*(ptr[i]+j)='\0';
break;
}
*(ptr[i]+j)=c;
j++;
}
printf("%s \n",ptr[i]);
i++;
}
}
}
getch();
free(ptr);
return 0;
}
Your problem is you increment i first at the beginning of the for-loop, second at the end of the loop, thus two times instead of one. You need to remove the i++; at the end.
Notes:
don't cast the result of malloc
you need to free the char*s you allocated (i.e. "ptr[i]")
use ptr[i][j] = c; instead of *(ptr[i] + j) = c;
confine the scope of variables as much as possible
use fgets to read from stdin
buffer overflows are possible in your code; another argument for fgets
I've missed a week of class in which they covered pointers but I haven't been able to get the notes from class but my HW is due and I still don't understand how to use pointers to pass strings from function to function... below is my code in which I realize the pointers are beyond messed up but I've tried to read other forums but just get lost. Any help is appreciated.
#include <stdio.h>
char* returnInPlace(char);
int palindrom(char, char );
main(void)
{
char newString[20];
printf("Enter a string: ");
scanf("%s",&newString);
char flippedString[20]=reverseInPlace(newString);
int palCheck= palindrome(newString, flippedString);
if (palCheck==0)
printf("\n\tThe reverse string is %s, so we don't have a palindrome.", flippedString);
else
printf("\n\tThe reverse string is %s, so we do have a palindrome.", flippedString);
}
char* reverseInPlace(char newString)
{
int iterator;
char flipped[20];
char *ptr1;
for(iterator=0;iterator<20;iterator++)
{
flipped[iterator]=firstString[19-iterator];
}
ptr1=flipped[];
return *ptr1;
}
int palindrome(char newString, char flippedString)
{
int iterator;
int palCheck=1;
for(iterator=0;iterator<20;iterator++)
{
if (firstString[iterator]==secondString[iterator])
continue;
else
{
palCheck=0;
break;
}
}
return palCheck;
}
Problem 1
In char* reverseInPlace(char newString), you're using
return *ptr1;
which is wrong. What you may want is
return ptr1;
Problem 2
ptr1=flipped[];
is wrong. Here, you're assigning the base address of a local variable flipped and returning that value. flipped will cease to exist after reverseInPlace() finishes execution. You need to use dynamic memory allocation.
Problem 3
char flippedString[20]=reverseInPlace(newString);
is wrong. You cannot assign an array with = unless as initialization at time of definition.
Problem 4
char* reverseInPlace(char newString)
this function definition looks wrong by seeing the way it is being called. Maybe what you want is
char* reverseInPlace(char* newString)
instead.
......and maybe many more. Strongly suggest to read some good book about Pointers and C basics before jumping into writing code.
I'm writing a C program which begins by opening and reading a file of 50 movie titles, each written on a single line. Next I am attempting to assign each line (or movie title) of the file into each element of an array called FilmArray[51]. I am using strcpy() to do so but the program crashes each time it reaches the first loop of the strcpy and I cannot seem to figure out where I've gone wrong...
int main()
{
int i=0;
char array[51];
char FilmArray[51];
bool answer;
FILE *films;
films = fopen("filmtitles.txt", "r");
if(films == NULL){
printf("\n ************* ERROR *************\n");
printf("\n \"filmtitles.txt\" cannot be opened.\n");
printf("\n PROGRAM TERMINATED\n");
exit(EXIT_FAILURE);
}
while(fgets(array, sizeof array, films) != NULL){
printf("%d. %s",i, array);
strcpy(FilmArray[i], array);
i++;
}
FilmArray is an array of characters, not an array of strings.
So when you're doing
strcpy(FilmArray[i], array);
the compiler will convert the value in FilmArray[i] to a pointer and use that as the destination of the string. This will lead to undefined behavior.
In fact, the compiler should be shouting a warning at you for this, and if it doesn't then you need to enable more warnings because warnings are messages about things that the compiler think are suspect and may lead to UB.
Your code is essentially trying to do an integer to pointer conversion passing char to parameter of type char *. Try using & with strcpy :
strcpy(&FilmArray[i], array);
& designates the use of a pointer for FilmArray[i]
suggest the following code
which compiles with no errors/warnings
is complete (given the posted code)
eliminates a lot of the code clutter
eliminates the 'magic' numbers buried in the code
#include<stdio.h>
#include<stdlib.h>
#define MAX_NUM_FILMS (51)
#define MAX_FILM_TITLE_LEN (51)
int main()
{
int i=0;
char FilmArray[ MAX_NUM_FILMS ][ MAX_FILM_TITLE_LEN ] = {{'\0'}};
FILE *films;
films = fopen("filmtitles.txt", "r");
if(films == NULL)
{
printf("\n ************* ERROR *************\n");
printf("\n \"filmtitles.txt\" cannot be opened.\n");
printf("\n PROGRAM TERMINATED\n");
exit(EXIT_FAILURE);
}
// implied else, fopen successful
while(fgets(&FilmArray[i][0], MAX_FILM_TITLE_LEN, films))
{
printf("%d. %s\n",i, FilmArray[i]);
i++;
}
// other code here
fclose( films ); // cleanup
return(0);
} // end function: main
In the following code, the printed result for char array dir is gibberish.
However, if I comment out the indicated printf statement, the printed result is intelligible. What is going on here? Thanks. sing code blocks / gcc.
#include <stdio.h>
#include <string.h>
char* handle_input(int argc,char *argv[]){
char dir[200];
printf("Number of arguments: %d\n",argc);
if(argc<2) {
printf("No argument specified\n");
strcpy(dir,"Default argument");
}
else{
printf("Command line directory was specified\n");
++argv;
strcpy(dir,argv[0]);
}
strcat(dir,"_CAT");
return dir;
}
int main(int argc, char *argv[]){
char* dir;
dir = handle_input(argc,argv);
printf("This one messes it up!\n");
printf("%s\n",dir);
printf("DONE\n");
return 0;
}
In your handle_input function, you're returning a local array, which is a huge no-no; after the function ends, that array no longer exists, and what you return is just nonsense. This invokes undefined behavior later in your program. That printf call happens to overwrite the memory which previously belonged to the array. Without the printf call, that memory just happens to be intact, which is why it comes out intelligibly.
The right way to return an array is like this:
char* handle_input(int argc,char *argv[]){
char* dir = malloc(200 * sizeof(char)); // sizeof unnecessary for char,
// but it's a good habit to have
printf("Number of arguments: %d\n",argc);
if(argc<2) {
printf("No argument specified\n");
strcpy(dir,"Default argument");
}
else{
printf("Command line directory was specified\n");
++argv;
strcpy(dir,argv[0]); // This is unsafe! use strncpy instead
}
strcat(dir,"_CAT");
return dir;
}
Using malloc ensures that the memory allocated will continue to exist after the end of the function, and that you will no longer be causing undefined behavior. Note that arrays are somewhat "special"; you can return primitive values (int, char, etc) and structs without having this sort of behavior occur.
You are returning a local char dir[200] in the function handle_input, after the function exits, it's undefined behavior to access it.
Use dynamic memory allocation instead, like:
char* handle_input(int argc,char *argv[]){
char *dir = malloc(200);
//do the processing
return dir;
}
Remember to free it once it's out of use.
You are returning a local vasriable
Either
Use malloc (as you are in the C world with printf)
Pass in a pointer to be filled up