-1

我正在尝试在 C 中执行此操作,我在 Python 中有一些代码,但我不知道如何使它在 C 中工作,我已经习惯了高级语言,而 C 对我来说真的很新,也许你可以帮我翻译一下,我什么都没有,因为我不知道从哪里开始......

Python代码:

archivo = open('passwd.txt')
for linea in archivo:
        campos = linea.strip().split(':')
        print 'User',campos[0],'has shell',campos[6]
archivo.close()

passwd.txt 如下:

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh

输出应该是:

User root has shell /bin/bash
User daemon has shell /bin/sh
User bin has shell /bin/sh

谁能帮我?

4

4 回答 4

1

它有点复杂,但基本上你需要知道两个关键的事情。我不会告诉你如何使用它们来做你想做的事,而只是展示如何使用它们。

第一个是逐行读取文件。这可以按如下方式完成:(来源

FILE *file = fopen ( filename, "r" );
char line [ 128 ]; /* or other suitable maximum line size */
while ( fgets ( line, sizeof line, file ) != NULL ) /* read a line */
{
  fputs ( line, stdout ); /* write the line */
}
fclose ( file );

第二个是解析行。这里最好的工具是strtok. (示例来源

 const char string[] = "words separated by spaces -- and, punctuation!";
 const char delimiters[] = " .,;:!-";
 char *token, *cp;

 ...

 cp = strdupa (string);                /* Make writable copy.  */
 token = strtok (cp, delimiters);      /* token => "words" */
 token = strtok (NULL, delimiters);    /* token => "separated" */
 token = strtok (NULL, delimiters);    /* token => "by" */
 token = strtok (NULL, delimiters);    /* token => "spaces" */
 token = strtok (NULL, delimiters);    /* token => "and" */
 token = strtok (NULL, delimiters);    /* token => "punctuation" */
 token = strtok (NULL, delimiters);    /* token => NULL */

将两者放在一起,并弄清楚如何获得正确的节点,然后就可以了。祝你好运!

于 2012-12-07T01:57:10.820 回答
1

@MatteoItalia 在评论中提出了一个很好的观点(关于以这种方式将 C 拼凑在一起)。这个问题最初是发布的,说明它是任务的一部分——正如 Matteo 所指出的,我不会任何类型的“真实”代码建议这个过程。


当人们不展示他们所做的事情时,您会看到人们感到沮丧的原因是因为这里的大多数人都喜欢学习和解决问题。我和这个网站上的大多数人不属于同一个房间,但我认为我们都分享这一点:)

我对 C 完全一无所知,但这是我要解决的问题。正如其他人所提到的,互联网和一些点连接基本上可以帮助您解决任何问题,所以一定要使用它:)

首先要做的事情 - 如何在 C 中打开文件?让我们谷歌一下。跳到它谈论打开的部分,看看代码是这样的:

FILE *fp;
fp=fopen("test.txt", "r");

我知道我需要将它放入将使用 C 编译器编译的文件中,但我不知道如何运行它(使用 Linux)。再次谷歌。看起来你使用gcc-o看起来它意味着output并将返回一个名为我键入的任何文件的文件,最后一个参数是 C 文件本身。

gcc -o learning learning.c

现在我在编译/运行时遇到错误,我将假设它是因为我需要做的不仅仅是键入上面的代码。谷歌多一点。看起来我需要添加一些名为“标题”的东西。这些看起来像 Python 库,也许它们提供了额外的功能(根据我有限的 Python 经验,我知道 C 似乎被认为是非常优化的,所以也许优化的一部分来自不包括某些功能作为“内置”。同样,不确定,只是猜测)。

#include <stdio.h>
#include <conio.h>
void main() {
  FILE *fp;
  fp = fopen("passwrd.txt", "a");
  fprintf(fp, "%s\n ", "Hello World, Where there is will, there is a way.");
  fclose(fp) ;
}

对我来说,这会导致conio.h. 我稍后会调查它,但现在删除并重试。现在它可以工作了,将该行添加到文件中。但是我不想要这个 - 我想读取文件。我会尝试更改ar(因为它看起来像 Python a,我假设它的意思是append;r会读)。我还将删除其他参数fprint,看看会发生什么。没有骰子,显然我需要学习如何读取文件。谷歌和我看到了这个:

while( ( ch = fgetc(fp) ) != EOF )
   printf("%c",ch);

我将它放在我的代码中代替fprintf(fp);,得到另一个关于未声明的变量和库的错误,将它们添加进去并获得以下内容,这很有效:

#include <stdio.h>
#include <stdlib.h>

void main() {
  char ch, file_name[25];
  FILE *fp;
  fp = fopen("passwd.txt", "r");

  while( ( ch = fgetc(fp) ) != EOF )
        printf("%c",ch);

  fclose(fp);
}

现在我需要在拆分字符串时打印第一个和最后一个值。不知道该怎么做,让我们检查一下互联网(和SO)。好吧,让我们进入一个新库,看看我们是否可以拆分内容。我将保存复制/粘贴,但我遇到越来越多的错误。我对编程知之甚少,但我遇到的一切似乎都表明分配、变量声明等方面的错误。我终于得到了一些工作(在找到一种从文件中读取行的新方法之后——另一种方式看起来像是字符)。结合我之前所学的fprint(看起来它的行为类似于 Python 中的字符串格式),我得到了这个:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main ( void )
{
  char *token;
  char *search = ":";
  char line[256];
   static const char filename[] = "passwd.txt";
   FILE *file = fopen ( filename, "r" );
   if ( file != NULL )
   {
      char line [ 128 ];
      while ( fgets ( line, sizeof line, file ) != NULL )
      {
         token = strtok(line, search);
         printf("First: %s\n", token);
      }
      fclose ( file );
   }
   else
   {
      perror ( filename );
   }
   return 0;
}

现在我需要结尾——我找到了这个,并看到我可以strtok对字符串进行大量调用并将其分块。做一些关于如何循环和得到这个的更多研究:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main ( void )
{
  char *token;
  char *search = ":";
  char line[256];
   static const char filename[] = "passwd.txt";
   FILE *file = fopen ( filename, "r" );
   if ( file != NULL )
   {
      char line [ 128 ]; /* or other suitable maximum line size */
      while ( fgets ( line, sizeof line, file ) != NULL ) /* read a line */
      {
         token = strtok(line, search);
         int counter;
         for (counter = 0; counter < 5; counter ++)
             strtok(0, search);
         char *last = strtok(0, search);
         printf("User %s has shell %s", token, last);
      }
      fclose ( file );
   }
   else
   {
      perror ( filename ); /* why didn't the file open? */
   }
   return 0;
}

完美吗?没门。我知道它是做什么的吗?有点,但我需要进行更多研究以更好地理解它。总而言之,找到一种方法把它分成小块——答案可能在不同的地方,但它们几乎总是在那里:)

于 2012-12-07T02:38:18.960 回答
0

据我所知,如果您需要在 C 中操作文件。您可以使用 fopen() 打开文本。 http://msdn.microsoft.com/en-us/library/yeby3zcb%28v=VS.71%29.aspx 而且,您可以使用“EOF”来获取每个令牌。像这样:

while(gets() != EOF)

所以,你可以得到每一行int text,只要把它保存在一个字符串中,printf就可以了。

于 2012-12-07T01:58:44.710 回答
0
#include <stdio.h>
#include <string.h>

int main(void) {
   FILE *fp = fopen("/etc/passwd", "r");
   char line[999];
   while (fgets(line, sizeof line, fp)) {
      char *user = strtok(line, ":");
      char *shell;
      int i;
      for (i = 0; i < 4; i++)
         strtok(0, ":");
      shell = strtok(0, ":");
      printf("User %s has shell %s\n", user, shell);
   }
   fclose(fp);
   return 0;
}

但是,如果 /etc/passwd 有空字段,由 表示::strtok则将不起作用。您可以strsep改为使用,或仅使用strchr,如:

#include <stdio.h>
#include <string.h>

int main(void) {
   FILE *fp = fopen("/etc/passwd", "r");
   char line[999];
   while (fgets(line, sizeof line, fp)) {
      char *user = line;
      char *p = line;
      char *shell;
      int i;
      for (i = 0; i < 6; i++)
         p = strchr(p + 1, ':');
      shell = p + 1;
      strchr(user, ':')[0] = 0;
      printf("User %s has shell %s", user, shell);
   }
   fclose(fp);
   return 0;
}

在我的机器上,一些所谓的 GECOS 字段是空的,并且用户news没有 shell。

于 2012-12-07T02:05:02.867 回答