Writing a Basic "C" Program in Mac Terminal - c

I was curious if I could write C programs in the Mac Terminal. It seems yes, but when I start trying to use Strings, I get errors when compiling.
#include <stdio.h>
#include <string.h>
int main(void) {
string s = "chris";
printf("hello %s \n", s);
}
When I compile this I get a message saying use of undeclared identifier 'string' - string s = "chris";
I have trying adding using namespace std; but is says that using is undefined. I have tried both #include <string> and #include <string.h>
Any thoughts would be appreciated.

string is a standard C++ library class. Use const char * instead:
#include <stdio.h>
int main(int argc, const char **argv) {
const char *s = "chris";
printf("hello %s \n", s);
return 0;
}

Related

Why does defining a function in C shows a weird error of putting ')' before a variable

Wen I try to compile my file stack-zero.c with the command gcc stack-zero.c -o stack0 it show this as error stack-zero.c:19:17: error: expected ‘)’ before ‘LEVELNAME’
The code is as follows
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define BANNER \
"Welcome to " LEVELNAME ", brought to you by https://exploit.education"
char *gets(char *);
int main(int argc, char **argv) {
struct {
char buffer[64];
volatile int changeme;
} locals;
printf("%s\n", BANNER);
locals.changeme = 0;
gets(locals.buffer);
if (locals.changeme != 0) {
puts("Well done, the 'changeme' variable has been changed!");
} else {
puts(
"Uh oh, 'changeme' has not yet been changed. Would you like to try "
"again?");
}
exit(0);
}
LEVELNAME is not defined. Define it and the problem is gone. Adding #define LEVELNAME "Ultimate level" before BANNER would compile and yield output as expected.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define LEVELNAME "Ultimate level"
#define BANNER \
"Welcome to " LEVELNAME ", brought to you by https://exploit.education"
char *gets(char *);
int main(int argc, char **argv) {
struct {
char buffer[64];
volatile int changeme;
} locals;
printf("%s\n", BANNER);
locals.changeme = 0;
gets(locals.buffer);
if (locals.changeme != 0) {
puts("Well done, the 'changeme' variable has been changed!");
} else {
puts(
"Uh oh, 'changeme' has not yet been changed. Would you like to try "
"again?");
}
exit(0);
}
In C programming language, the character " is considered to be a special character, as it defines the opening and closing of a string.
Try using your BANNER definition like this:
#define BANNER \
"Welcome to \" LEVELNAME \", brought to you by https://exploit.education"

I am using this code to print from text file but the program gives me "-1.#IND00"

I have a problem. I am using this code to print from text file but the program gives me a different number -such as 11732408.000000- each time. However I don't get this problem when ex is integer.
#include <stdio.h>
#include <string.h>
int main() {
char example[] ="123.12/456 ";
double ex = atof(strtok(example, "/"));
printf("%lf", ex);
return 0;
}
I could solve my problem. Thank you for your helps.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main ()
{
char example[20] ="123.12/456 ";
double ex=atof(strtok(example,"/"));
printf("%lf",ex);
return 0;
}
You forgot to include <stdlib.h> which contains the declaration of atof().
Your compiler is lenient and accepts your code is spite of the missing declaration, and it incorrectly infers the prototype to be int atof(char *), which causes undefined behavior when storing the return value to ex.
Hence the bogus output.
Note also that the l in the format %lf is necessary for scanf() but ignored by printf() as float arguments are implicitly converted to double when passed to vararg functions.
Here is a corrected version:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char example[] = "123.12/456 ";
char *p = strtok(example, "/");
if (p != NULL) {
double ex = atof(p);
printf("%f\n", ex);
}
return 0;
}

Functions and strings

im very new to programming, trying to learn C and cant figure out how to create/use a simple function.
Im trying to create a function called stringtest and then call it into the main and simply make the string strA print ABC.
void stringtest(char strA[20])
{
strA = "ABC";
}
int main()
{
char strA;
stringtest(strA[20]);
printf("This is strA", strA);
return 0;
}
You need to read up on pointers and the C syntax in general.
This is one way you could do it.
#include <stdio.h>
#include <string.h>
void stringtest(char *strA) {
strcpy(strA, "ABC");
}
int main(int argc, const char * argv[]) {
char strA[20];
stringtest(&strA[0]);
printf("This is strA -> %s \n", strA);
return 0;
}
Take care,
/Anders.
I don't think your code ran!!
There are a lot of bugs and errors in your code.
See the code given below to understand how to do this:
#include <stdio.h>
char strA[20];
void stringtest(){
strA[0]='A';
strA[1]='B';
strA[2]='C';
strA[3]='\0';
}
int main(){
stringtest();
printf("This is strA %s",strA);
}

C: Command line arguments with string

I'm trying to write a program that takes a string as a command line argument and then runs said argument through a function (str_to_int) that takes a string as an input. However, when I try to compile the program, I get a warning saying
initializing 'char *' with an expression of type 'int' [-Wint
conversion]
char* str = atoi(argv[1]);
^ ~~~~~~~~~~~~~
And when I run the program I get a segmentation fault
I've tested the str_to_int a lot so I'm pretty sure that the issue lies with the command line program. Here's the code for it.
#include "hw3.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, char *argv[])
{
char* str = atoi(argv[1]);
printf("%d\n", str_to_int(str));
return 0;
}
Can anyone tell me what I'm doing wrong? Thanks.
This is all you need, though it will crash if you leave out the command-line argument.
{
printf("%d\n", str_to_int(argv[1]));
return 0;
}
This is more robust:
int main(int argc, char *argv[])
{
if (argc == 1)
printf("missing parameter.");
else
printf("%d\n", str_to_int(argv[1]));
return 0;
}
#include "hw3.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, char *argv[])
{
char* str = argv[1];
printf("%d\n", str_to_int(str));
return 0;
}
just remove atoi function invocation and it should work

Passing command line arguments through a C setuid wrapper to another script

I have the following c setuid wrapper:
#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>
main( int argc, char ** argv ) {
struct passwd *pwd;
char user[] = "cvmfs-test";
pwd = getpwnam(user);
setuid(pwd->pw_uid);
system(argv[1]);
}
I can call my perl script with ./cwrapper perlscript.pl.
I would like to do ./cwrapper perlscript.pl --option1 --option2 --option3 and elaborate all arguments inside the perl script with GetOptions. How should I change my wrapper?
There is also a nice solution which does not need any allocation, is able to deal with arbitrary long commands and does not imply running useless processes because it does not use system. Moreover with the following solution you get the exit code of the spawned process for free.
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include <pwd.h>
#define SETUIDUSER "foobar"
int main(int argc, char **argv) {
struct passwd *pwd;
char user[] = SETUIDUSER;
pwd = getpwnam(user);
// success test needed here
setuid(pwd->pw_uid);
// success test needed here
if (argc < 2)
return 1;
execvp(argv[1], &argv[1]);
return 42;
}
Here is a version dealing with a variable number of arguments. Please note that your syscalls should be tested to ensure everything is going OK.
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include <pwd.h>
#define CMDMAXLGTH 4096
#define SETUIDUSER "testuser"
int main( int argc, char ** argv ) {
struct passwd *pwd;
char user[] = SETUIDUSER;
char buf[CMDMAXLGTH];
char *p = buf;
int i = 1;
pwd = getpwnam(user);
// success test needed here
setuid(pwd->pw_uid);
// success test needed here
memset (buf, 0, sizeof(buf));
while (argv[i]) {
p += sprintf(p, " %s", argv[i++]);
}
system(buf);
return 0;
}
You should use sprintf to build a character string with your options, then pass this string to system:
char command [100];
sprintf (command, "./cwrapper %s --%s --%s --%s", program_name,option1,option2,
option3);
system(command);
Update: this approach assumes a fixed number of arguments, and looking back at your question, I see that may not be the case.
Ignore the argv[0] because is the name of the c program and use all the other. You can calculate (strlen) the required memory to assemble a new string, malloc() the memory for the new string and then build your new string by concatenating all the argv (strcat). Or for a fixed length approach, follow #dan1111 answer.

Resources