I have the following code:
#include <stdio.h>
#include <stdlib.h>
FILE * f_enter;
void CleanLineFeed(char * pCad)
{
char *cTmp;
char *ptr;
cTmp=pCad;
ptr = strtok(cTmp, "\r\n\r");
strcpy(pCad, ptr);
}
int main(int argc, char *argv[])
{
char datenter[127];
int i;
f_enter=fopen("data.txt","r");
if(f_enter == NULL)
{
printf("No data.txt.\n");
return 1;
}
while ( fgets(datenter, 127, f_enter) )
{
CleanLineFeed(datenter);
for(i=0; i < strlen(datenter);i++)
{
printf("%c-%0X\n",datenter[i], datenter[i]);
}
printf("----------------------\n");
}
return 0;
}
when i run it on Windows there is no error but
when i run it on Linux give me a segmentation fault error
Please, i strongly appreciate some kind of help
you forgot to
#include <string.h>
Man page on Ubuntu 14.04 for strcpy says "The strings may not overlap".
"CleanLineFeed" performs an overlapped strcpy().
( This Link describes the issue )
Windows implementation of "strcpy" may differ from Linux's implementation,
which may explain why one crashes and the other doesn't.
Related
I've been learning C for like 5 days, and so I tried doing some little projects.
I created a very simple library that automates getting a string from the user,then implemented it in a program which just outputs the string's value.
It runs perfectly on Windows (Compiled through MSVC: 'cl .\main.c /link .\get_string\m_string.obj') but it doesn't in Linux (Compiled with gcc using : 'gcc -o test main.c m_string.o')
I know that MAX being 1024 makes absolutely no sense, it's just a test value.
//main.c
#include <stdio.h>
#include "get_string/m_string.h"
int main(int argc, char *argv[])
{
char *inputf = get_string("Something: ");
printf("%s", inputf);
return 0;
}
// m_string.h
#include <stdio.h>
#define MAX 1024
char *get_string(char *prompt);
//m_string.c
#include "m_string.h"
char *get_string(char *prompt)
{
char *s[MAX];
printf("%s", prompt);
fgets(s, MAX, stdin);
return s;
}
Running main.c on Windows works as expected:
Something: something
something
Running main.c on Linux:
Something: something
(null)$
Since I am using a very big value for the maximum memory used in fgets(), I don't think that a buffer overflow is the cause (Would have probably gotten Segmentation Fault otherwise).
Thank you for reading and I hope someone can shed some light on the matter for an absolute beginer like me.
char *s[MAX]; creates an array of MAX pointers, not char values.
ALWAYS enable your compiler's warnings. It would have found this. With gcc, I use -Wall -Wextra -pedantic.
get_string returns a pointer to a variable that no longer exists once get_string returns.
One way to solve this is to allocate a buffer using malloc, and free that buffer in the caller.
#include <stdio.h>
#include <stdlib.h>
#define MAX 1024
char *get_string( const char *prompt ) {
char *s = malloc( MAX );
if ( !s )
return NULL;
printf( "%s", prompt );
if ( !fgets( s, MAX, stdin ) ) {
free( s );
return NULL;
}
return s;
}
int main( void ) {
char *inputf = get_string( "Something: " );
if ( !inputf ) {
perror( NULL );
exit( 1 );
}
printf( "%s", inputf );
free( inputf );
return 0;
}
Demo on Compiler Explorer
It really does not run "correctly", because this is undefined behavior. You may not access temporary storage outside of the scope in which it was defined.
In addition to this, you also have a type error: char *s[MAX]; defines an array of MAX char pointers. Using this as a string buffer should not have been allowed past the compiler.
If you do not want to allocate memory dynamically for this, then make the string buffer static. You can even make it thread-local (since C11) if for some reason you plan to use this function in concurrent environments.
#include <stdio.h>
#define MAX 1024
char *get_string(const char *prompt)
{
static _Thread_local char s[MAX];
printf("%s", prompt);
if (!fgets(s, MAX, stdin)) {
s[0] = '\0';
}
return s;
}
int main(int argc, char *argv[])
{
char *inputf = get_string("Something: ");
printf("%s", inputf);
return 0;
}
So I'm getting to know valgrind a bit and I've come across an example that has me confused.
I was shown this code causes a Invalid Write in valgrind:
#include <stdlib.h>
#include <stdlib.h>
int main(int argc, const char* argv[])
{
int index = atoi(argv[1]);
char *x = malloc(10);
x[index] = âfâ;
return 0;
}
while this code causes a segfault in valgrind:
int foo(y)
{
char str[10];
str[11] = âfâ;
return 0
}
So do these examples have anything to do with the fact that example 1 is something thats done on the heap while the 2nd example is done on the stack?
Am I missing something bigger?
Thanks
I want to write a script with C. Only run on the Ubuntu system.
I Get the name of the operating system.
But. I failed to define the if clause.
Thanks for the help
Like this algorithm:
I think the most reliable way of checking the OS name is to use the uname utility.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int match_OS(const char* name) {
FILE *p;
int result;
char *s = malloc(1024);
p = popen("uname -v", "r");
s = fgets(s, 1024, p);
result = (strstr(s, name) != NULL);
pclose(p);
free(s);
return result;
}
int main() {
if (match_OS("Ubuntu")) {
puts("This is Ubuntu");
}
else {
puts("This isn't Ubuntu");
}
return 0;
}
I want to parse a string into an array of tokens . '\n' and ';' are delimiters , for e.g. :
hello;hello
world
should be converted to an array containing: {"hello","hello","world"}.
I tried many different methods for doing this and always I fail (since it needs a dynamic array of char * I have trouble with implementing it).
Please note that I cannot use strtok or lexical analyzer.
How may I do this ? Any points ?
EDIT : here is one of methods I tried to use but I get segmentation fault (maybe a memory access issue somewhere in my code) :
#include <stdio.h>
#include <malloc.h>
#include <fcntl.h>
#include <string.h>
typedef struct {
int fd;
char *path;
int size;
char *mem;
struct stat st;
} file;
file *readfile(char *path) {
file *a=malloc(sizeof(file));
a->path=path;
a->fd=open(a->path,O_RDONLY);
if(a->fd<0) return 0;
fstat(a->fd,&a->st);
a->size=a->st.st_size;
a->mem=malloc(a->size);
read(a->fd,a->mem,a->size);
return a;
}
void releasefile(file *a) {
free(a->mem);
close(a->fd);
free(a);
}
char **parse(int *w,file *a) {
int i,j=0;
w=0;
for(i=0;i<=a->size;i++) {
if(a->mem[i]=='\n' || a->mem[i]==';') { a->mem[i]='\0'; j++; }
}
char **out=malloc(sizeof(char *)*j);
for(i=0;i<=a->size;i++) {
if(a->mem[i-1]!='\0') continue;
out[*w]=malloc(strlen(a->mem+i)+1);
memcpy(out[*w],a->mem+i,strlen(a->mem+i)+1);
w++;
return out;
}
int main(int argc,char **argv) {
file *a=readfile(argv[1]);
int *w=malloc(sizeof(int));
char **tokens=parse(w,a);
int i;
for(i=0;i<=*w;i++) {
puts(tokens[i]);
}
releasefile(a);
// ATM no need to check for mem leaks :)
}
Algorithm description : read file, put \0 where you see a delimiter, start and push tokens seprated by \0 into an array.
What has happened to computer science?
Anyway write a FSA - http://en.wikipedia.org/wiki/Finite-state_machine
Can do this using a table
I was trying to mimic strtok functionality but getting segmentation fault. Please help me out here.
Here is my code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char argv[])
{
int i=0;
char c[]="get the hell out of here";
char *p;
char *temp=(char *)malloc(100);
while(c[i]!='\0')
{
if(c[i]!=' ')
{
*temp=c[i];
temp++;
i++;
}
else
{
*temp='\0';
printf("printing tokenn");
puts(temp);
i++;
temp="";
}
}
return 0;
}
temp="";
This causes temp to point at unmodifiable memory, leading to a fault the next time you try to modify through it. You wanted to restore temp to the value you got from malloc (which you forgot to save).