I am using Debian 11
I am trying to reproduce strlcpy.
1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4
5 unsigned int ft_strlcpy(char *dest, char *src, unsigned int size)
6 {
7 unsigned int i;
8
9 i = 0;
10 while (src[i] && i < size)
11 {
12 dest[i] = src[i];
13 i++;
14 }
15 dest[i] = '\0';
16 while (src[i])
17 i++;
18 return (i);
19 }
20
21 int main()
22 {
23 unsigned int i;
24 char *dest1 = malloc(sizeof(char) * 50);
25 char *dest2 = malloc(sizeof(char) * 50);
26
27 i = 0;
28 while (i < 26)
29 {
30 printf("%d ", ft_strlcpy(dest1, "hello my name is marcel", i));
31 printf("%s\n", dest1);
32 printf("%ld ", strlcpy(dest2, "hello my name is marcel", i));
33 printf("%s\n", dest2);
34 i++;
35 }
36 free(dest1);
37 free(dest2);
38 return (0);
39 }
However, I get this message when I compile my code:
ft_strlcpy.c: In function ‘main’:
ft_strlcpy.c:32:18: warning: implicit declaration of function ‘strlcpy’; did you mean ‘strncpy’? [-Wimplicit-function-declaration]
32 | printf("%ld ", strlcpy(dest2, "hello my name is marcel", i));
| ^~~~~~~
| strncpy
/usr/bin/ld: /tmp/ccukR8g6.o: in function `main':
ft_strlcpy.c:(.text+0xf0): undefined reference to `strlcpy'
collect2: error: ld returned 1 exit status
make: *** [<builtin>: ft_strlcpy] Error 1
I have no idea how to include libbsd or use pkgconf.
I have tried for a couple of hours, but I couldn't find the solution.
If someone could redirect me to a manual or explain the concepts, that would be great.
Thank you for your help!
The strlcpy function is included in the BSD libc, a superset (extended version) of the POSIX standard library for BSD operating systems. For it to be recognized by the compiler you have to first install the library through your package manager, the name of which will be either libbsd, libbsd-dev or libbsd-devel depending on whether your distribution uses seperate development libraries or not, and than include it as <bsd/string.h>. You can then compile it with (assuming you use GCC) gcc <your-filename>.c -lbsd, specifying the library to be linked. I wouldn't recommended using BSD functions outside of BSD specific software due to portability issues (POSIX incompliences).
Related
i am using makefiles in c, i have three files and each of the three have all the declarations of each variable. so it looks like this when i compile.
/usr/bin/ld: comp_disc.o:(.bss+0x8): multiple definition of `Cost_of_purchase'; main.o:(.bss+0x8): first defined here
/usr/bin/ld: comp_disc.o:(.bss+0x10): multiple definition of `DiscTot'; main.o:(.bss+0x10): first defined here
/usr/bin/ld: comp_disc.o:(.bss+0x18): multiple definition of `Sales_tax'; main.o:(.bss+0x18): first defined here
/usr/bin/ld: comp_disc.o:(.bss+0x20): multiple definition of `Total_price'; main.o:(.bss+0x20): first defined here
/usr/bin/ld: comp_disc.o:(.bss+0x28): multiple definition of `military'; main.o:(.bss+0x28): first defined here
but when i only keep those declarations on main.c i get this.
comp_disc.c:10:12: error: ‘Cost_of_purchase’ undeclared (first use in this function)
10 | if(Cost_of_purchase > 150) {
| ^~~~~~~~~~~~~~~~
comp_disc.c:11:13: error: ‘Mdisc’ undeclared (first use in this function)
11 | Mdisc = .15 * Cost_of_purchase;
so I'm wondering what i need to do so that my variables are declared correctly using make
here is my makefile
# target : dependencies
2 cwork7 : main.o comp_disc.o print_res.o
3 gcc main.o comp_disc.o print_res.o -Wall -o cwork7
4
5 main.o : main.c
6 gcc -c main.c -Wall
7
8 comp_disc : comp_disc.c
9 gcc -c comp_disc.c -Wall
10
11 print_res.o : print_res.c
12 gcc -c print_res.c -Wall
my main.c
5 #include <stdio.h>
6 //functions prototypes
7 void compute_discount(void);
8 int print_results(void);
9
10
11 //defined Gloabal var
12 double Mdisc;
13 double Cost_of_purchase;
14 double DiscTot;
15 double Sales_tax;
16 double Total_price;
17 char military;
18
19 int main (void) {
20 //declare variables
21
22 //Cost of purchase
23 printf("Cost of purchase?\t\t$");
24 scanf ("%lf",&Cost_of_purchase);
25
26 //Military?
27 printf("In military (y or n)?\t\t");
28 scanf(" %c" ,&military);
29
30 //calling for functions
31 compute_discount();
32 print_results();
33
34 }
35
36
my print_res.c
1 #include <stdio.h>
2
3 //function to print results
4 int print_results(void){
5
6 //if input is y Y then use below, this is not dependant on if military only if the letter is accepted
7 switch(military){
8 case 'y':
9 case 'Y':
10 printf("Military discount (15%%): \t$%.2f\n", Mdisc);
11 printf("Discounted total: \t\t$%.2f\n", DiscTot);
12 printf("Sales tax (5%%): \t\t$%.2f\n", Sales_tax);
13 printf("Total: \t\t\t\t$%.2f\n", Total_price);
14 break;
15 //less information is given when n or N is used
16 case 'n':
17 case 'N':
18 printf("Sales tax (5%%): \t\t$%.2f\n", Sales_tax);
19 printf("Total: \t\t\t\t$%.2f\n", Total_price);
20 break;
21 }
22 return(0);
23 }
and my comp_disc.c
1 #include <stdio.h>
2
3 //function to compute discount
4 void compute_discount(void){
5
6 //compute military discount
7 switch(military){
8 case 'y':
9 case 'Y':
10 if(Cost_of_purchase > 150) {
11 Mdisc = .15 * Cost_of_purchase;
12 } else if (Cost_of_purchase < 150) {
13 Mdisc = .10 * Cost_of_purchase;
14 }
15 break;
16 case 'n':
17 case 'N':
18 Mdisc = 0;
19 break;
20 default:
21 printf("Error: bad input\n");
22 }
23
24 //cost minus military discount
25 DiscTot = Cost_of_purchase - Mdisc;
26 //sales tax
27 Sales_tax = .05 * DiscTot;
28 //Total Calculated
29 Total_price = DiscTot + Sales_tax;
30
31 }
Please let me know what you think is the issue.
This has nothing to do with the Makefile.
If you define the variables in all source file you get exactly what the linker says, multiple definitions of the same name. And if you drop them from the file you obviously get a compile error as you are using variables the compiler does not know about.
The simple solution is to keep the variables in main as-is, but to define them as extern in all other files, like extern double Cost_of_purchase; That tells the compiler the variable exists, but is already defined elsewhere, which solves the problem.
However, just don't use global variables. Pass your data to the functions.
struct acc_data {
double Mdisc;
double Cost_of_purchase;
double DiscTot;
double Sales_tax;
double Total_price;
char military;
}
int main(void)
{
struct acc_data acc = { 0 };
// init code skipped
compute_discount(&acc);
print_results(&acc);
}
void compute_discount(struct acc_data *acc)
{
//same as before but prefix variables with acc->
// example:
acc->Total_price = 5000.0;
}
That gets rid of your original problem and improves your code somewhat.
Put the definition of the struct in a header file you include in all C files that use it.
I'm trying to fill an array with a file called data.txt. I don't know what's wrong with code. I get segmentation fault: 11 error.
#include <stdio.h>
#include <stdlib.h>
void input(int arr[]){
FILE* f;
int x, i=0;
f= fopen("data.txt","r");
while (arr[i] != EOF){
fscanf(f,"%d",&x);
arr[i] = x;
i++;
}
fclose(f);
}
int main(){
int arr[50];
input(&arr[50]);
printf("%d", arr[0]);
}
You are reading the number into x (which you are copying into arr[i]) and then comparing arr[i+1] to EOF. That is not how it has to be done.
Try this
while (fscanf(f, "%d", &arr[i]) == 1)
i++;
But this would violate so many safety constraints. Better also bound check and break early if i is greater than some limit, but that limit should be passed to the function.
Another error is with how you are passing arguments to input. Pass input(arr) instead of input(&arr[50]). If you want to use & use input(&arr[0]).
This would be more nearly my version of your code:
#include <stdio.h>
#include <stdlib.h>
static int input(int size, int arr[])
{
const char file[] = "data.txt";
FILE *f = fopen(file, "r");
if (f == NULL)
{
fprintf(stderr, "Failed to open file '%s' for reading\n", file);
exit(EXIT_FAILURE);
}
int i;
for (i = 0; i < size && fscanf(f, "%d", &arr[i]) == 1; i++)
;
fclose(f);
return i;
}
int main(void)
{
int arr[50];
int num = input(50, arr);
for (int i = 0; i < num; i++)
printf("%d: %d\n", i, arr[i]);
return 0;
}
The use of static before the function is necessary to quell -Wmissing-prototypes. The main() function tells the input() function how many elements are in the array so the input() function can avoid overflowing the buffer (a stack overflow, no less). The input() function tells the main() function how many values it read, so the main() function doesn't go accessing data that was not initialized. The crucial function calls are error checked — fopen() and fscanf().
The code compiles cleanly on a Mac running macOS Sierra 10.12.4 using GCC 6.3.0 and the command line below (the source file was rf19.c):
$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes \
> -Wstrict-prototypes -Wold-style-definition rf19.c -o rf19
$
I generated a data file with 23 random integers between 10 and 99 in it, and the output was:
$ ./rf19
0: 48
1: 33
2: 77
3: 42
4: 78
5: 51
6: 85
7: 56
8: 55
9: 56
10: 16
11: 38
12: 39
13: 52
14: 34
15: 63
16: 20
17: 23
18: 23
19: 19
20: 39
21: 44
22: 71
$
That's not dreadfully informative, but better than nothing.
The code has deficiencies still, which I don't plan to fix — some more serious than others. For example, the file name is fixed — that's a no-no. The code in the input() function exits on error; that isn't necessarily OK. It produces an error message on standard error — that's better than standard output, but wouldn't be a good idea in a GUI application. The output wastes a lot of horizontal space; with the data shown, you could get 10 values per output line (that would use about 70 characters per line), but the printing for that is more intricate, so I didn't show it. The code treats EOF and a word or punctuation character in the data the same; that might or might not matter, depending on your application. The input simply stops after the 50th entry; maybe you need to know whether there were more entries available to read. I'd probably process the command line arguments as file names, or process standard input if no files were specified — the Unix 'filter command' idiom. I'd probably do something more exciting than just print the first fifty values. I'd probably put the file reading code in a separate function from the file open/close code.
I have the following program in Mingw, gcc 4.9.2:
#include <stdio.h>
#include <stdint.h>
#define VECSIZE 32
typedef char byteVec __attribute__ ((vector_size (VECSIZE)));
#define PERMLEFT_BVEC (byteVec){63,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30}
byteVec permute(byteVec x, byteVec y) {
return __builtin_shuffle(x,y,PERMLEFT_BVEC);
}
void print_vec32b(byteVec a) {
printf("[ ");
int i; for (i = 0; i < 32; ++i) printf("%d ", a[i]);
puts("]");
}
int main() {
byteVec x = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32};
byteVec y = {11,12,13,14,15,16,17,18,19,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,88,89,90,91,92};
byteVec z = permute(x,y);
print_vec32b(x);
return 0;
}
When I compile this program with -m64, it crashes. With -m32 it works fine. Optimization level doesn't matter. I don't understand what's going on. I've also tried TDM with GCC 5.1.0. Same thing. Anybody have any advice? Is it something screwy with GCC in Windows?
Here is the assembly produced by the compiler (note how the shuffle is turned into a permutation automatically, with vperm2i128 and vpalignr, which is the desired behavior:
GCC Explorer
Minimal program: above.
Desired behavior: print permuted byte vector (which it does in 32-bit mode).
Expected output (works in 32-bit mode):
$ gcc nvec.c -m32 -mavx2 -o a.exe && a.exe
[ 92 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ]
Actual result: crash.
Description of crash: immediate crash, windows error reporting bug shows up. No errors or warnings.
#include <stdio.h>
#include <stdlib.h>
#include <uuid/uuid.h>
int main(void) {
puts("!!!Hello World!!!"); /* prints !!!Hello World!!! */
uuid_t uuid;
int uuid_generate_time_safe(uuid);
printf("%x",uuid);
return EXIT_SUCCESS;
}
I just wonder why uuid is not 16 bytes long?
I use DEBUG to view the memory, It is indeed not 16 bytes.
And I use libpcap to develop my program, The uuid is not unique.
I just tried your program on my system, and uuid is 16 bytes long. But your program doesn't display its size.
The line:
int uuid_generate_time_safe(uuid);
isn't a call to the uuid_generate_time_safe function, it's a declaration of that function with uuid as the (ignored) name of the single parameter. (And that kind of function declaration isn't even valid as of the 1999 standard, which dropped the old "implicit int" rule.)
Your printf call:
printf("%x",uuid);
has undefined behavior; "%x" requires an argument of type unsigned int.
If you look in /usr/include/uuid/uuid.h, you'll see that the definition of uuid_t is:
typedef unsigned char uuid_t[16];
The correct declaration of uuid_generate_time_safe (see man uuid_generate_time_safe) is:
int uuid_generate_time_safe(uuid_t out);
You don't need that declaration in your own code; it's provided by the #include <uuid/uuid.h>.
Because uuid_t is an array type, the parameter is really of type unsigned char*, which is why the function is seemingly able to modify its argument.
Here's a more correct program that illustrates the use of the function:
#include <stdio.h>
#include <uuid/uuid.h>
int main(void) {
uuid_t uuid;
int result = uuid_generate_time_safe(uuid);
printf("sizeof uuid = %d\n", (int)sizeof uuid);
// or: printf("sizeof uuid = %zu\n", sizeof uuid);
if (result == 0) {
puts("uuid generated safely");
}
else {
puts("uuid not generated safely");
}
for (size_t i = 0; i < sizeof uuid; i ++) {
printf("%02x ", uuid[i]);
}
putchar('\n');
return 0;
}
On my system, I got the following output:
sizeof uuid = 16
uuid not generated safely
26 9b fc b8 89 35 11 e1 96 30 00 13 20 db 0a c4
See the man page for information about why the "uuid not generated safely" message might appear.
Note that I had to install the uuid-dev package to be able to build and run this program.
I think this code and error is self-explanatory, but I don't know why?
Environment:
OS: Mac OS X 10.6.1
Compiler: i686-apple-darwin10-gcc-4.2.1
code:
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <netdb.h>
4 #include <sys/socket.h>
5
6 int
7 main(int argc, char **argv)
8 {
9 char *ptr, **pptr;
10 struct hostent *hptr;
11 char str[32];
12
13 //ptr = argv[1];
14 ptr = "www.google.com";
15
16 if ((hptr = gethostbyname(ptr)) == NULL) {
17 printf("gethostbyname error for host:%s\n", ptr);
18
19 }
20 printf("official hostname:%s\n", hptr->h_name);
21
22 for (pptr = hptr->h_aliases; *pptr != NULL; pptr++)
23 printf(" alias:%s\n", *pptr);
24
25 switch (hptr->h_addrtype) {
26 case AF_INET:
27 case AF_INET6:
28 pptr = hptr->h_addr_list;
29
30 for (; *pptr != NULL; pptr++)
31 printf(" address:%s\n", inet_ntop(hptr->h_addrtype, *pptr, str, sizeof(str)));
32 break;
33 default:
34 printf("unknown address type\n");
35 break;
36 }
37 return 0;
38 }
compiler and executed output below:
zhumatoMacBook:CProjects zhu$ gcc gethostbynamedemo.c
gethostbynamedemo.c: In function ‘main’:
gethostbynamedemo.c:31: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘int’
zhumatoMacBook:CProjects zhu$ ./a.out
official hostname:www.l.google.com
alias:www.google.com
Segmentation fault
Why am I getting the format warning and could this be the cause of the segmentation fault?
Please compile your code using -Wall.
include header file for inet_ntop (arpa/inet.h)
read inet_ntop(3) man page and be careful about parameter types.
If I count right, the warning is emitted for this line:
printf(" address:%s\n", inet_ntop(hptr->h_addrtype, *pptr, str, sizeof(str)));
According to this page, inet_ntop does indeed return char*. However, apparently you don't include <arpa/inet.h> - this can cause this warning, as the compiler may default to interpret an undeclared function as one returning an int.
Next time, please mark the problematic code line(s) with e.g. a comment - it would increase your chances of getting useful answers :-)