I'm a newbie in C programming and having pretty simple code here.
It compiles but won't run and a segmentation fault appears. I was looking for hours what could be wrong. Now I have a pretty good idea what segmentation fault means but not why it shows up in my small piece of code:
It's supposed to print out the user_id and group_id of the given parameter.
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <pwd.h>
int main(int argc, char *argv[]){
if(argc != 1){
printf("ERROR");
}
struct passwd str;
struct passwd *pointer = getpwnam(argv[1]);
str = *pointer;
printf("user: %d /ngroup: %d",str.pw_uid, str.pw_gid);
return 0;
}
You should check pointer != NULL before assign it into str.
getpwnam() return NULL in case no entry was found or an error occurred. See https://linux.die.net/man/3/getpwnam for more detail.
I can detect some problems here:
Check if number of arguments is greater than 0, otherwise exit your program
You should check if return value from getpwnamreturns NON-NULL value.
I would rewrite this to:
int main(int argc, char *argv[]){
struct passwd str;
struct passwd *pointer;
//Number of arguments check
if (argc <= 1) {
printf("ERROR");
exit(0);
}
pointer = getpwnam(argv[1]);
if (pointer) {
str = *pointer;
printf("user: %d /ngroup: %d\r\n",str.pw_uid, str.pw_gid);
printf("user: %d /ngroup: %d\r\n", pointer->pw_uid, pointer->pw_gid);
}
return 0;
}
You probably want this:
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <pwd.h>
int main(int argc, char *argv[]){
if(argc < 2){
printf("usage: %s username", argv[0]);
return 1;
}
struct passwd *pointer = getpwnam(argv[1]);
if (pointer == NULL) {
printf("user: %s does not exist\n", argv[1]);
return 1;
}
printf("uid: %d\ngroup: %d\n", pointer->pw_uid, pointer->pw_gid);
return 0;
}
You need to check if getpwnam returns NULL. If yes, that means that the user does not exist and dereferencing a NULL pointer results in undefined behaviour (usually a seg fault).
BTW: the variable struct passwd str is not needed, you can access pointer directly.
Related
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
char *ptr;
char temp[20];
if (strlen(argv[1]) < strlen(argv[2]))
{
strcpy(temp,argv[1]);
strcpy(argv[1],argv[2]);
strcpy(argv[2],temp);
}
ptr = strstr(argv[1],argv[2]);
if (ptr == NULL)
printf("Non-inclusive");
else
printf("%s is part of %s", argv[2], argv[1]);
return 0;
}
When I enter "abc abcd",
I want to get "abc is part of abcd" as a result,
but real result is "abc is part of abcdabc"
The length of each string in the argv array is fixed. So when you attempt to swap the contents of argv[1] and argv[2] when their sizes are different you write past the end of the shorter one. This triggers undefined behavior.
Better to use separate char * variables, one pointing the longer string and one pointer to the shorter.
int main(int argc, char *argv[])
{
char *ptr;
char *s_short, *s_long;
if (strlen(argv[1]) < strlen(argv[2])) {
s_short = argv[1];
s_long = argv[2];
} else {
s_short = argv[2];
s_long = argv[1];
}
ptr = strstr(s_long,s_short);
if (ptr == NULL)
printf("Non-inclusive");
else
printf("%s is part of %s", s_short, s_long);
return 0;
}
I am trying to read line by line a standard file input.
This is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define BUFFER_SIZE 1204
char* readLine(char* buffer){
int i = 0;
for(i; i< BUFFER_SIZE; i++){
printf("%c",buffer[i]);
if( '\n' == buffer[i]){
char* line[124];
memcpy( line, &buffer[0], i-1 );
return *line;
}
}
free(buffer);
}
int doStuffWithLine(char* line){
return 1;
}
int main(int argc, char *argv[])
{
ssize_t aux1;
char *buffer = malloc(sizeof(char)*BUFFER_SIZE);
char *line = malloc(sizeof(char)*BUFFER_SIZE);
while((read(STDIN_FILENO, buffer, BUFFER_SIZE))>0){
line = readLine(buffer);
doStuffWithLine(line);
printf("%s", line);
}
return 0;
}
This is the input file content:
lol1
lol2
lol3
And this is the output of my program:
lol1
Segmentation fault (core dumped)
I want to know how read lines 2 and 3, solve it and a little explanation about what I am doing wrong because I do not understand the problem.
Thank you in advance.
Function read reads in raw bytes and will not terminate your buffer with a string termination character '\0'; Using it then for printf("%s",...), which expects a 0-terminated C-string, yields undefined behaviour (e.g. a crash).
I'd suggest to use fgets instead.
First of all, thank you all that helped me and spent some time trying it.
After spending some hours learning and breaking my brain I have found a solution. In conclusion I am ***** and noob.
If someone is having the same problem I am submitting my code. Easy peasy:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>
char* doStuff(char* line){
return line;
}
int main(int argc, char *argv[])
{
char *line = malloc(sizeof(char)*LINE_MAX);
while(fgets(line, LINE_MAX, stdin)!= NULL)
{
line = doStuff(line);
printf("%s", line);
}
return 0;
}
I am new to C and I have had trouble simplifying this program. I am trying to initalize name once and strcat name to command once. It is a command line executable that takes two args and one optional arg for the filename "new py" or "new txt", or "new py script". I run Windows's MinGW to compile.
Is there a type to allow storage of argv value and a string constant with one line?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
char command[100] = "cd . > ";
char *type = argv[1];
char * name;
strcat(command,"\"");
if (argc == 3) {
char * name = argv[2];
//strcat(command,name);
} else {
char name[20];
sprintf(name,"new %s file",type);
//strcat(command,str);
}
strcat(command,name);
strcat(command,".");
strcat(command,type);
strcat(command,"\"");
system(command);
return 0;
}
As mentioned by BLUEPIXY, my block needs to include "char name[20]; if(argc == 3){ strcpy(name, argv[2]); } else { sprintf(name,"new %s file",type); } strcat(command, name);". After those changes, I converted all of the strcats to one sprinf.
My previous understanding of storing argv items was that char pointers were needed for compilation because args wouldn't be defined. They are not needed any more because of the initialization of name.
My now condensed code is this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
char command[100];
char * type = argv[1];
char name[50];
if (argc == 3) {
strcpy(name, argv[2]);
} else {
sprintf(name,"new %s file",type);
}
sprintf(command,"cd . > \"%s.%s\"",name,type);
system(command);
return 0;
}
Again, thank you BLUEPIXY for clearing my misunderstanding.
I know there is a BoF in the program, but the buffer is not exceded with "AA", then, why I obtain "segmentation fault"?...
$ gcc program.c -o program
$ ./program AA
Segmentation fault
This is the source:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void func(char *arg)
{
char name[32];
strcpy(name, arg);
printf("\nWelcome, %s\n\n", name);
}
int main(int argc, char *argv[])
{
if (argc != 2)
{
printf("Use: %s YOUR_NAME\n", argv[0]);
exit(0);
}
func(argv[2]);
printf("The end\n\n");
return 0;
}
You dereference a null pointer. argv[argc] is defined as being NULL.
I think you meant func( argv[1] ); . Arrays index from zero in C.
I am trying to print each char in a variable.
I can print the ANSI char number by changing to this printf("Value: %d\n", d[i]); but am failing to actually print the string character itself.
What I am doing wrong here?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int len = strlen(argv[1]);
char *d = malloc (strlen(argv[1])+1);
strcpy(d,argv[1]);
int i;
for(i=0;i<len;i++){
printf("Value: %s\n", (char)d[i]);
}
return 0;
}
You should use %c format to print characters in C. You are using %s, which requires to use pointer to the string, but in your case you are providing integer instead of pointer.
The below will work. You pass in the pointer to a string when using the token %s in printf.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int len = strlen(argv[1]);
char *d = malloc (strlen(argv[1])+1);
strcpy(d,argv[1]);
printf("Value: %s\n", d);
return 0;
}