I want count the characters (in various charsets) in a file and I'm using the function 'mbtowc' to detect the characters. I cannot figure out why the chars and results values are different. Here is my example:
char buf[BUFFER_SIZE + MB_LEN_MAX];
int fd = open ("chinese_test", O_RDONLY);
unsigned int bytes, chars;
int bytes_read;
bytes = chars = 0;
while((bytes_read = read(fd, buf, BUFFER_SIZE)) > 0) {
wchar_t wc_buf[BUFFER_SIZE], *wcp;
char *p;
int n = 0;
bytes += bytes_read;
p = buf;
wcp = wc_buf;
while((n = mbtowc(wcp, p, MB_LEN_MAX)) > 0) {
p += n;
wcp++;
chars++;
}
}
printf("chars: %d\tbytes: %d\n", chars, bytes);
I test the function with a text with some GB2312 characters, but chars and bytes are too different values.
My test returns -> chars: 4638 | bytes: 17473
but 'wc' linux command returns: chars: 16770 | bytes: 17473
Why this difference? What did I do wrong?
Now I've this code but there are still soe difference in the result.
char buf[BUFFER_SIZE * MB_LEN_MAX];
int fd = open ("test_chinese", O_RDONLY), filled = 0;
unsigned int bytes, chars;
int bytes_read;
bytes = chars = 0;
while((bytes_read = read(fd, buf, BUFFER_SIZE)) > 0) {
wchar_t wc_buf[BUFFER_SIZE], *wcp;
char *p;
int n = 0;
bytes += bytes_read;
p = buf;
wcp = wc_buf;
while(bytes_read > 0) {
n = mbtowc(NULL, p, MB_LEN_MAX);
if (n <= 0) {
p++;
bytes_read--;
continue;
}
p += n;
bytes_read -= n;
chars++;
}
}
printf("\n\nchars: %d\tbytes: %d\n", chars, bytes);
The problem is a combination of your BUFFER_SIZE, the file size of chinese_test and the byte alignment of wchar_t. As proof, try drastically increasing BUFFER_SIZE- you should start getting the answer you want.
What is happening is that your program works for the first block of text that it receives. But think about what happens in your code if a character is split between the first and second blocks as follows:
| First Block | Second Block |
| [wchar_t] [wchar_t] ... [wchar_t] [wchar_t] ... |
| [1,2,3,4] [1,2,3,4] ... [1,2,3,4] [1,2,3,4] ... |
Your code will begin the second block on the 3rd byte in the first character, and that will not be recognized as a valid character. Since mbtowc will return -1 when it does not find a valid character, your loop will immediately end and will count zero characters for that entire block. The same will apply for the following blocks.
EDIT:
Another issue I noticed is that you need to set the locale in order for mbtowc to work correctly. Taking all of these issues into account, I wrote the following which returns the same character count as wc for me:
#include <stdlib.h>
#include <stdio.h>
#include <locale.h>
int BUFFER_SIZE = 1024;
const char *DEFAULT_F_IN = "chinese_test";
struct counts {
int bytes;
int chars;
};
int count_block(struct counts *c, char *buf, int buf_size)
{
int offset = 0;
while (offset < buf_size) {
int n = mbtowc(NULL, buf + offset, MB_CUR_MAX);
if (n <= 0) {
break;
}
offset += n;
c->bytes += n;
c->chars++;
}
return buf_size - offset;
}
void get_counts(struct counts *c, FILE *fd)
{
char buf[BUFFER_SIZE];
c->bytes = 0;
c->chars = 0;
int bytes_read;
while((bytes_read = fread(buf, sizeof(*buf), BUFFER_SIZE, fd)) > 0) {
int remaining = count_block(c, buf, bytes_read);
if (remaining == 0) {
continue;
} else if (remaining < MB_CUR_MAX) {
fseek(fd, -remaining, SEEK_CUR);
} else {
perror("Error");
exit(1);
}
}
}
int main(int argc, char *argv[]) {
FILE *fd;
if (argc > 1) {
fd = fopen(argv[1], "rb");
} else {
fd = fopen(DEFAULT_F_IN, "rb");
}
setlocale(LC_ALL, "");
struct counts c;
get_counts(&c, fd);
printf("chars: %d\tbytes: %d\n", c.chars, c.bytes);
return 0;
}
Related
So I am trying to make a function print_file_rows() that prints the first ten rows of a file. If the file has more than 10 rows it works perfectly fine but if there's 10 or less it starts printing garbage. Any ideas on how I can fix this? (MUST ONLY USE THE SYSTEM FUNCTIONS OPEN/READ/WRITE/CLOSE)
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
void print_file_rows(char *path)
{
int fd = open(path, O_RDONLY);
if (fd < 0)
{
return NULL;
}
size_t size = 100;
size_t offset = 0;
size_t res;
char *buff = malloc(size);
while((res = read(fd, buff + offset, 100)) != 0)
{
offset += res;
if (offset + 100 > size)
{
size *= 2;
buff = realloc(buff, size);
}
}
close(fd);
int j = 0;
for(int i = 0;buff[i] != '\0'; i++)
{
if(j == 10)
{
break;
}
if(buff[i] == '\n')
{
j++;
}
printf("%c", buff[i]);
}
free(buff);
}
int main()
{
print_file_rows("a.txt");
return 0;
}
You do not need any buffers. It is most likely buffered on the OS level so you may print char by char.
int print_file_rows(char *path, size_t nrows)
{
int result = -1;
int fd = open(path, O_RDONLY);
char c;
if (fd > 0)
{
while(nrows && read(fd, &c, 1) == 1)
{
write(STDOUT_FILENO, &c, 1);
if(c == `\n`) nrows--;
}
result = nrows;
}
close(fd);
return result;
}
int main()
{
if(print_file_rows("a.txt", 10) == -1)
printf("Something has gone wrong\n");
return 0;
}
From man 2 read:
SYNOPSIS
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
DESCRIPTION
read() attempts to read up to count bytes from file descriptor fd into the buffer starting at buf.
read is for reading raw bytes, and as such has no notion of strings. It does not place a NUL terminating byte ('\0') at the end of the buffer. If you are going to treat the data you read as a string, you must terminate the buffer yourself.
To make room for this NUL terminating byte you should always allocate one extra byte in your buffer (i.e., read one less byte that your maximum).
We can see the return value is actually of type ssize_t, rather than size_t, which allows for
On error, -1 is returned, and errno is set to indicate the error.
This means we will need to check that the return value is greater than zero, rather than not zero which would cause the offset to be decremented on error.
With all that said, note that this answer from a similar question posted just yesterday shows how to achieve this without the use of a dynamic buffer. You can simply read the file one byte at a time and stop reading when you've encountered 10 newline characters.
If you do want to understand how to read a file into a dynamic buffer, then here is an example using the calculated offset to NUL terminate the buffer as it grows. Note that reading the entire file this way is inefficient for this task (especially for a large file).
(Note: the call to write, instead of printf)
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
void print_file_rows(const char *path)
{
int fd = open(path, O_RDONLY);
const size_t read_size = 100;
size_t size = read_size;
size_t offset = 0;
ssize_t res;
char *buff = malloc(size + 1);
while ((res = read(fd, buff + offset, read_size)) > 0) {
offset += res;
buff[offset] = '\0';
if (offset + read_size > size) {
size *= 2;
buff = realloc(buff, size + 1);
}
}
close(fd);
int lines = 0;
for (size_t i = 0; lines < 10 && buff[i] != '\0'; i++) {
write(STDOUT_FILENO, &buff[i], 1);
if (buff[i] == '\n')
lines++;
}
free(buff);
}
int main(void)
{
print_file_rows("a.txt");
}
(Error handling omitted for code brevity. malloc, realloc, and open can all fail, and should normally be handled.)
I've been developing a guessing game in which the goal is to guess the character selected by the user among specific characters, anyway, my first and only idea is to create an array with the questions to be asked, and each question has its options like in the code below I'm a newbie in C language so that I there are several things which I'm not sure how to handle. In short, I'd like to know how can I loop over the array showing to the user the questions with its questions to be answered? Here's the code.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#define ROW 500
#define LINE 200
//Read file and append to an array buffer
char *characters(){
char *source = NULL;
FILE *fp = fopen("file.txt", "r");
if (fp != NULL) {
/* Go to the end of the file. */
if (fseek(fp, 0L, SEEK_END) == 0) {
/* Get the size of the file. */
long bufsize = ftell(fp);
if (bufsize == -1) { /* Error */ }
/* Allocate our buffer to that size. */
source = malloc(sizeof(char) * (bufsize + 1));
/* Go back to the start of the file. */
if (fseek(fp, 0L, SEEK_SET) != 0) { /* Error */ }
/* Read the entire file into memory. */
size_t newLen = fread(source, sizeof(char), bufsize, fp);
if ( ferror( fp ) != 0 ) {
fputs("Error reading file", stderr);
} else {
source[newLen++] = '\0'; /* Just to be safe. */
}
}
fclose(fp);
}
return source;
}
char *strndup(const char *s, size_t n) {
char *p;
size_t n1;
for (n1 = 0; n1 < n && s[n1] != '\0'; n1++)
continue;
p = malloc(n + 1);
if (p != NULL) {
memcpy(p, s, n1);
p[n1] = '\0';
}
return p;
}
// User input
char *input(){
char *value;
char buffer[10];
int j = 0;
while( j < 1 && fgets(buffer, 10, stdin) != NULL){
value = strndup(buffer, 10);
j++;
}
return value;
}
// Main function
int main (void)
{
char *questions[] = {
"Genre",{"male","female"},
"Hair", {"black","red","blond"},
"Cloths",{"dress","shirt","pants"},
"pet", {"dog","cat","pig"}
};
int asked[4] = {0};
char *answers[5];
char buffer[6];
srand(time(NULL));
for (int i = 0; i < 4; i++) {
int q = rand() % 4;
while (asked[q])
q = rand() % 4;
asked[q]++;
printf ("%s\n", questions[q]);
answers[i] = input();
}
for(int i = 0; i < 4; i++)
{
printf(" %s ",answers[i]);
}
return 0;
}
That's the file's structure I'll compare as long as I have all the answers from the user.
female,blond,vestido,pig,character b
male,black,shirt,pants,dog,character c
male,black,shirt,pants,cat,character d
female,blond,dress,cat,character A
male,red,shirt,pants,pig,character e
I am trying to get the read() system call to read my file line by line and reverse each line to stdout. My issue is getting read() to read my file line by line because normally it just reads the whole file. I want the LINE_BUFFER size to be the max size a line can be.
I tried implementing a function to try to do this but it seems to break the program and I am a little lost on how to approach this problem.
Here is my code:
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#define LINE_BUFFER 1024
int charCount(const char *name1);
ssize_t readline (char *buf, size_t a, int b, off_t *offset);
int main(int argc, char* argv[]) {
if(argc ==2){
charCount(argv[1]);
}else{
printf("Provide a file\n");
}
return 0;
}
int charCount(const char *name1)
{
char buffer[LINE_BUFFER];
int fd;
ssize_t len = 0;
int nread;
int i = 0;
off_t offset = 0;
if ((fd = open(name1, O_RDONLY)) == -1)
{
perror("Error in opening file");
return (-1);
}
int size = lseek(fd,-1, SEEK_END);
while(size>=0)
{
while((len = readline(buffer,LINE_BUFFER,fd,&offset)) != -1){
write(1,buffer,1);
lseek(fd, -2,SEEK_CUR);
size--;
}
}
close(fd);
return(0);
}
ssize_t readline(char *buf, size_t a, int b, off_t *offset)
{
int fd;
ssize_t nchr =0;
ssize_t idx =0;
char *p = NULL;
if ((nchr = lseek(fd, *offset, SEEK_SET)) != -1){
nchr = read(fd,buf,a);
}
p = buf;
while(idx<nchr && *p != '\n') p++,idx++;
*p =0;
if(idx == nchr) {
*offset + nchr;
return nchr < (ssize_t)a ? nchr : 0;
}
*offset += idx+1;
return idx;
}
I'm not sure what you mean when you say that "normally it just reads the whole file". read has a fairly low maximum size it will read, typically 4KiB or 8KiB. In any case, I put together some code to reverse line of a file.
#include <assert.h>
#include <fcntl.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int xopen(const char *, int);
void * Realloc(void *, size_t);
void reverse(char *, char *);
char * findchr(char *, char *, char);
int
main(int argc, char **argv)
{
ssize_t rc;
size_t siz = BUFSIZ; /* size available to read into */
char *buf = Realloc(NULL, BUFSIZ + siz); /* Pad the front */
char *s = buf + BUFSIZ; /* first char of a line */
char *prev = s; /* start of data from previous read */
char *end = s; /* one past last char read from input */
int fd = argc > 1 ? xopen(argv[1], O_RDONLY) : STDIN_FILENO;
while(( rc = read( fd, s, BUFSIZ )) > 0 ) {
char *eol; /* A newline, or one past valid data */
end = s + rc;
if( (eol = findchr(s, end, '\n')) == end ) {
/* No newlines found in the last read. Read more. */
if( end > buf + siz ) {
ptrdiff_t e_off = end - buf;
ptrdiff_t p_off = prev - buf;
siz += BUFSIZ;
buf = Realloc(buf, BUFSIZ + siz);
eol = end = buf + e_off;
prev = buf + p_off;
}
s = end;
assert( s <= buf + siz );
continue;
}
s = prev;
do {
assert(*eol == '\n');
assert(eol < end);
reverse(s, eol-1);
s = eol + 1;
assert(s <= end);
} while( (eol = findchr(s, end, '\n')) < end );
assert(eol == end);
assert(eol[-1] != '\n' || s == end);
fwrite(prev, 1, s - prev, stdout);
prev = buf + BUFSIZ - (end - s);
memcpy(prev, s, end - s);
eol = s = buf + BUFSIZ;
}
if(rc == -1) {
perror(argc > 1 ? argv[1] : "stdin");
return EXIT_FAILURE;
}
if(prev < s) {
reverse(prev, s-1);
fwrite(prev, 1, s - prev, stdout);
}
return EXIT_SUCCESS;
}
/*
* Find v between str and end. If not found,
* return end. (This is basically strchr, but
* doesn't care about nul.)
*/
char *
findchr(char *str, char *end, char v) {
assert(str <= end);
while( str < end && *str != v )
str += 1;
return str;
}
void
reverse(char *start, char *end)
{
for( ; start < end; start++, end-- ) {
char tmp = *end;
*end = *start;
*start = tmp;
}
}
void *
Realloc( void *buf, size_t s )
{
buf = realloc( buf, s );
if( buf == NULL) { perror("realloc"); exit(EXIT_FAILURE); }
return buf;
}
int
xopen(const char *path, int flag)
{
int fd = open(path, flag);
if( fd == -1 ) { perror(path); exit(EXIT_FAILURE); }
return fd;
}
I wrote a C program to perform an XOR encryption,
my problem is that the program is not able to encrypt files with more than 24 characters.
The code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define BUF_SIZE 2
char* xor(char*, char*);
char* gen_key(size_t);
int main(int argc, char **argv) {
char *buffer = NULL,* encrypted_buffer = NULL;
size_t file_size;
char *key = gen_key(6);
char tmp_buffer[BUF_SIZE];
FILE *finput = NULL, *foutput = NULL;
finput = fopen("file.txt", "rb");
fseek(finput, 0, SEEK_END);
file_size = ftell(finput);
rewind(finput);
printf("File size : %d\n", (int)file_size);
buffer = (char*)malloc((file_size + 1) * sizeof(char));
memset(buffer, 0, sizeof(buffer));
while (!feof(finput)) {
memset(tmp_buffer, 0, sizeof(tmp_buffer));
fgets(tmp_buffer, sizeof(tmp_buffer), finput);
strcat(buffer, tmp_buffer);
}
printf("%s", buffer);
encrypted_buffer = xor(buffer, key);
free(buffer);
buffer = xor(encrypted_buffer, key);
printf("Encrypted : %s\n", encrypted_buffer);
printf("Decrypted : %s\n", buffer);
printf("EOF\n");
free(encrypted_buffer);
fclose(finput);
return 0;
}
char *gen_key(size_t length) {
srand(time(NULL));
const char charset[] = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz012345679";
const size_t charset_size = (sizeof(charset) - 1);
unsigned int i;
char *key = NULL;
key = (char*)malloc((length + 1) * sizeof(char));
memset(key, 0, sizeof(key));
for (i = 0; i < length; i++)
key[i] = charset[rand() % charset_size];
return key;
}
char *xor(char *file, char *key) {
unsigned int i;
char *xor = NULL;
xor = (char*)malloc(sizeof(file));
memset(xor, 0, sizeof(xor));
for (i = 0; i < strlen(file); i++)
*(xor + i) = *(file + i) ^ *(key + (i % strlen(key) - 1));
return xor;
}
And the output is :
File size : 55
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklimnopqrstuvwxyz
Encrypted : A2#G8- M >7S$1!
Decrypted : ABCDEFGHIJKLMNOPQRSTUVWX!:!e!
EOF
There are multiple problems in your code:
The buffer size is very small: #define BUF_SIZE 2. You should use a reasonable size for the line buffer, such as 80 or 100.
in memset(buffer, 0, sizeof(buffer));, buffer is a pointer, so sizeof(buffer) is not the size of the array, just the size of the pointer. Use file_size + 1 in this case.
You make the same mistake in other places in your code: pass the size of the buffers instead of relying on the sizeof() operator.
while (!feof(f)) is always wrong: you could jut use fread to read the file in one step or read line by line with:
while (fgets(tmp_buffer, sizeof(tmp_buffer), finput)) {
...
Note that there is a major problem with your approach: the key is composed of letters and digits and the file is assumed to contain text. If the file contains one of the characters in the key at the appropriate position, xoring this character with the key byte will produce a null byte that will stop the output in printf() and that would also stop the decryption if you were to store it in an output file. You rightfully use binary mode ("rb") for the file stream, but you should also make no assumptions on the file contents and handle null bytes transparently.
Here is a modified version of your program:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
unsigned char *xor(unsigned char *file, size_t size, const char *key);
char *gen_key(size_t length);
void print_buffer(const char *msg, unsigned char *buf, size_t size) {
printf("%s: ", msg);
for (size_t i = 0; i < size; i++) {
switch (buf[i]) {
case '\n':
printf("\\n");
break;
case '\\':
printf("\\\\");
break;
default:
if (buf[i] >= ' ' && buf[i] < 127)
putchar(buf[i]);
else
printf("\\%02x", buf[i]);
break;
}
}
printf("\n");
}
int main(int argc, char **argv) {
long file_size, nread, nwritten;
unsigned char *buffer, *encrypted_buffer, *decrypted_buffer;
char *key = gen_key(6);
FILE *finput = fopen("file.txt", "rb");
if (finput == NULL) {
fprintf(stderr, "cannot open file.txt: %s\n", strerror(errno));
return 1;
}
fseek(finput, 0, SEEK_END);
file_size = ftell(finput);
rewind(finput);
printf("File size: %ld\n", file_size);
buffer = calloc(file_size, sizeof(char));
nread = fread(buffer, 1, file_size, finput);
if (nread != file_size) {
fprintf(stderr, "error reading file.txt: read %ld bytes, expected %ld\n",
nread, file_size);
}
fclose(finput);
FILE *foutput = fopen("output.bin", "wb");
if (foutput == NULL) {
fprintf(stderr, "cannot open output.bin: %s\n", strerror(errno));
return 1;
}
encrypted_buffer = xor(buffer, nread, key);
nwritten = fwrite(encrypted_buffer, 1, nread, foutput);
if (nwritten != nread) {
fprintf(stderr, "error writing output.bin: wrote %ld bytes, expected %ld\n",
nwritten, nread);
}
fclose(foutput);
decrypted_buffer = xor(encrypted_buffer, nread, key);
printf("Key : %s\n", key);
print_buffer("Original ", buffer, nread);
print_buffer("Encrypted", encrypted_buffer, nread);
print_buffer("Decrypted", decrypted_buffer, nread);
if (!memcmp(decrypted_buffer, buffer, nread))
printf("OK\n");
free(decrypted_buffer);
free(encrypted_buffer);
free(buffer);
return 0;
}
char *gen_key(size_t length) {
const char charset[] = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz012345679";
const size_t charset_size = sizeof(charset) - 1;
char *key = (char*)calloc(length + 1, sizeof(char));
size_t i;
srand(time(NULL));
for (i = 0; i < length; i++)
key[i] = charset[rand() % charset_size];
return key;
}
unsigned char *xor(unsigned char *file, size_t size, const char *key) {
size_t i, keylen = strlen(key);
unsigned char *xor = calloc(size, sizeof(char));
for (i = 0; i < size; i++)
xor[i] = file[i] ^ key[i % keylen];
return xor;
}
I'm writing a program that takes a file with the 3 lines of encrypted passwords and compares them to all 4 lower case letters from aaaa - zzzz. The only issue I am having is that I can't figure out how to go line by line of the file I input and how to compare it to the 4 letter words individually. It should then print the 3 decrypted 4 letter words that correlate to the passwords from the file. Also if there are any types on how to improve my code, please let me know. I'm a beginner at this so I need clear explanations and examples if possible. Thank you.
EDIT*****
The main problem is in the all function and main. I'm not wanting to print the aaaa, aaab, aaac, etc to the screen but I want to put it in an char array so that i can compare each individually to each line from the file using crypt. So I need advice on how to put all 456976 combinations into an array, compare it to each line of code, and print the solutions to the screen.
file looks like this:
$1$6gMKIopE$I.zkP2EvrXHDmApzYoV.B.
$1$pkMKIcvE$WQfqzTNmcQr7fqsNq7K2p0
$1$0lMKIuvE$7mOnlu6RZ/cUFRBidK7PK.
My code looks like this:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define BUFFER_SIZE 1024
int my_fgets(char* buf, int len, int f)
{
for (int i = 0; i < len; i++,buf++)
{
int count = read(f, buf, 1);
if (!count || (buf[0] == '\n'))
{
buf[0] = 0;
return i;
}
}
return 0;
}
int inc(char *c,char begin, char end){
if(c[0]==0)
return 0;
if(c[0] == end){ // This make the algorithm to stop at char 'f'
c[0]=begin; // but you can put any other char
return inc(c+sizeof(char), begin, end);
}
c[0]++;
return 1;
}
char all(int a, int n,char begin, char end){
int i, j;
char *c = malloc((n+1)*sizeof(char));
char result[] = "";
for(i = a; i <= n; i++)
{
for(j=0;j<i;j++) c[j]=begin;
c[i]=0;
do {
int k = sizeof(result);
for (int g = 0; g < k -1; g++)
{
result[g] = c;
}
} while(inc(c,begin,end));
}
free(c);
}
int main(int argc, char* argv[])
{
char *result;
char let[456976];
int f = open("pass.txt", O_RDONLY);
if (f < 0)
return 0;
char buf[1024];
while (my_fgets(buf, sizeof(buf), f))
{
let = all(4,4,'a','z');
int i = 0;
result = crypt((let[i+1]), buf);
int ok = strcmp (result, pass) == 0;
return ok ? 0 : 1;
all(4, 4, 'a', 'z');
}
close(f);
}
I think you need to reword the question. Maybe the code below is what you want. Let's say you have a password, and you have a file which contains a list of encrypted passwords (or hash usually), you want to see if password is right or wrong. You compare the hash of the password with hashes in the file. I haven't tested this code.
ps, let me know if I am way off, I'll delete the answer.
void crypt(char* hash, const char* password_test) {
//create hash from password, or encrypt it or something?
}
int test_password(const char *filename, const char *password){
FILE *f;
f = fopen(filename, "r");
if (!f) return 0;
char password_hash[256];
crypt(password_hash, password);
char hash[256];
char buf[1024];
while (fgets(buf, sizeof(buf), f) != NULL)
{
crypt(hash, buf);
if (strcmp(password_hash, hash) == 0)
return 1;
}
fclose(f);
return 0;
}
void main() {
int result = test_password("test.txt", "password");
if (result == 1)
printf("password is good\n");
}
Reading line by line using open/read/close
int my_fgets(char* buf, int len, int f)
{
for (int i = 0; i < len; i++,buf++)
{
int count = read(f, buf, 1);
if (!count || (buf[0] == '\n'))
{
buf[0] = 0;
return i;
}
}
return 0;
}
int main(){
int f = open("test.txt", O_RDONLY);
if (f < 0) return 0;
char buf[1024];
while (my_fgets(buf, sizeof(buf), f))
printf("%s\n", buf);
close(f);
}