我正在尝试编写一个程序,该程序将读取用户提供的.txt文件,并使其输出哈希列表。到目前为止,这就是我所掌握的,我无法弄清楚如何打开文件并散列单个单词。而是散列文件名。
#include < stdio.h >
#include < string.h >
#include "md5.h"//char *md5(const char *str, int length);
#include < stdlib.h >
int main(int argc, char * argv[]) //argc: # of arguments argv: inputand utput
{
FILE * fp;
fp = fopen(argv[1], "r");
if (!fp) {
printf("Can't open %s for reading\n", argv[1]);
exit(1);
}
FILE * out;
if (argc != 3) //(argc < 2 || argc > 3)
{
printf("Usage: %s word_to_hash [output_file]\n", argv[0]);
exit(1);
}
out = fopen(argv[2], "w");
FILE * fpout;
if (argc == 3) {
fpout = fopen(argv[2], "w");
if (!fpout) {
printf("Can't open %s for writing\n", argv[2]);
exit(1);
}
}
char line[100];
while (fgets(line, 100, fp) != NULL) {
if (argc == 3) fclose(fpout);
if (argc != 3) //(argc < 2 || argc > 3)
{
fprintf("%s", "r");//printf("Usage: %s word_to_hash [output_file]\n", argv[0]);
exit(1);
}
out = fopen(argv[2], "w");
if (argc == 3) {
out = fopen(argv[2], "w");
if (!out) {
printf("Can't open %s for writing.\n", argv[1]);
exit(2);
}
}
else
out = stdout;
char * hash = md5(argv[1], strlen(argv[1]));
fprintf(out, "%s\n", hash);
if (argc == 3)
fprintf(fpout, "%s", line);
else
printf("%s", line);
}
// Close file
fclose(fp);
}
// clang hashpass.c md5.c -o hashp -l crypto
//../ hashp words.txt output.txt
^这些分别是我用来编译和运行程序的内容。 Words.txt是我试图读取我的代码的单独文件。非常感谢能正确打开文件的任何帮助。
答案 0 :(得分:2)
您的代码的主要问题是-它听起来像是杂乱无章的事情,您认为尝试做一个好主意,所以您添加了它们,编译了它,失败了,更改了一些东西,编译了,它失败了, (然后您重复一遍,直到您如此绝望地迷路了,您需要寻求帮助)–那不是您编程的方式...
编程,每个表达式都有其含义,如果您希望编写能够完成任何任务的程序,则必须准确理解每个表达式的功能。这样做的方法是拿起铅笔和纸,并概述完成任务所需执行的步骤。然后,您研究语言提供的功能以使您完成每个步骤,并通过参考文档了解如何正确使用每个功能(对于您拥有的每个功能,可以是Linux手册页,MSDN页面或C-Standard。决定使用)。
您需要先完成所有 操作,然后拿起键盘并开始查看您的代码。虽然看起来这种方法需要大量的精力和时间-您用“猜测,编译,失败,重复” 方法浪费了多少时间?正确的方法实际上会缩短从头到尾花费的时间。
好的,在这样的背景下,很明显,您需要一点帮助才能指出正确的方向。正如您现在可能已经猜到的那样,在您的代码中对out = fopen(argv[2], "w");
进行3次调用是毫无意义的,这真是令人困惑,为什么您会从fp
中读取一行然后立即关闭{{1} }(认为它从未使用过),例如
fpout
此外,您已经陷入了写 while (fgets(line, 100, fp) != NULL) {
if (argc == 3) fclose(fpout);
或argv[2]
的逻辑中。对于这种大小的代码,这就是简单的外壳 redirection 的用途(在Linux,Windows和Mac上相同)。不必担心打开输出文件,只需写入stdout
,如果要输出到文件,则可以在命令行上将输出重定向到文件,例如>
从stdout
读取并写入stdin
stdout
从$ yourprogram < somefile
读取并将stdin
重定向到文件
stdout
您可以执行同样的操作来读取用$ yourprogram < somefile > output file
打开的文件,只需删除开头的fopen (name, "r")
。
以这种方式处理输入和输出可简化读写,让您专注于代码的主要目标。
考虑到这一点,您可以删除代码中的大部分内容,只需打开'<'
给出的文件以进行读取(或者,如果未提供任何参数,则只需从argv[1]
中读取)即可默认)。下面的示例正是这样做的,并且将stdin
用于MD5哈希,因为我们无法知道您的<openssl/md5.h>
所包含的内容。此外,如果定义了"md5.h"
(通过在编译器选项中简单地包含HASHLINE
),以下示例将对输入中的每个 line 进行哈希处理,或者对每个 word进行哈希处理默认情况下,如果未定义-DHASHLINE
。该示例使用其他代码进行编码,因为完全不清楚是要在描述和变量名中同时使用哈希值来对每个 word 或 line 进行哈希处理。
一个简短的例子是:
HASHLINE
(注意:如果您不确定如何编译代码,请让我知道您使用的是哪个编译器,我很乐意提供编译字符串)
示例输入文件
#include <stdio.h>
#include <string.h>
#include <openssl/md5.h>
#define MAXC 1024 /* if you need a constant, #define one - don't skimp */
int main(int argc, char **argv) {
char word[MAXC] = ""; /* word/line buffer */
unsigned char hash[MD5_DIGEST_LENGTH] = ""; /* buffer to hold hash */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin; /* file or stdin */
if (!fp) { /* validate file open for reading */
perror ("file open failed");
return 1;
}
#ifndef HASHLINE
while (fscanf (fp, "%s", word) == 1) { /* read word at a time */
const char *fmt = "%-16s : "; /* printf (fmt, ...) for words */
#else
while (fgets (word, MAXC, fp)) { /* read line at a time */
const char *fmt = "%-32s : "; /* printf (fmt, ...) for lines */
word[strcspn (word, "\n")] = 0; /* remove trailing '\n' */
#endif
size_t len = strlen (word); /* get length of word/line */
int index = 0, /* index for output hex char */
n = MD5_DIGEST_LENGTH; /* md5 hash length */
MD5 ((const unsigned char *)word, len, hash); /* compute hash */
printf (fmt, word); /* output word/line */
while (n--)
printf ("%02x", hash[index++]); /* output hash */
putchar ('\n'); /* tidy up with newline */
}
if (fp != stdin) fclose (fp); /* close file if not stdin */
}
使用/输出示例
散列每一行,并使用定义的$ cat dat/captnjack.txt
This is a tale
Of Captain Jack Sparrow
A Pirate So Brave
On the Seven Seas.
进行编译,例如通过将HASHLINE
命令行选项传递给编译器:
-DHASHLINE
哈希每个单词(如果未定义$ ./bin/wordsmd5sslline dat/captnjack.txt
This is a tale : 3495386196b8aef7d65ae857a8a5f4dc
Of Captain Jack Sparrow : 225057b50358205942eafa11a35e4028
A Pirate So Brave : 3f3498d45e5f3be24ae264768dcbb4c8
On the Seven Seas. : 390ab96392602d0e78ae28b30444481f
,则为默认值):
HASHLINE
仔细检查一下,如果还有其他问题,请告诉我。