做来自K&R的5.7项练习:
重写读行以将行存储在main提供的数组中,而不是调用alloc来维护存储。这个程序有多快?
程序所做的是使用一个指针数组指向一组行,这些行已经通过一个快速排序算法排序,然后打印出来。
我选择一个巨大的数组,total_lines[]存储由getline()获取的每一行,我使用指针p指向Total_lines[]中每一行的开头,这样我就可以将这些行开始的指针地址存储在指针lineptr[]数组中
但是,当我从copy_lines()返回到readlines()后,在自动窗口中出现了一个错误:p 0x00000000 <Bad Ptr>,它没有复制到这里的指针数组:lineptr[nlines++] = p;
下面是出错的代码:
#define MAXLEN 1000
int getline (char *, int);
char *alloc(int);
int copy_lines(char total_lines[], char line[], char *p);
int readlines (char *lineptr[], int maxlines, char total_lines[], int max_chars)
{
int len, nlines;
char *p, line[MAXLEN];
p = 0;
nlines = 0;
while((len = getline(line, MAXLEN)) > 0)
if (nlines >= maxlines)
return -1;
else{
line [len-1] = '\0';
copy_lines(total_lines, line, p);
//strcpy(p, line);
lineptr[nlines++] = p;
printf("%s\n", lineptr);
}
return nlines;
}
int copy_lines(char total_lines[], char lines[], char *p)
{
static int i = 0;
int j = 0;
total_lines[i] = lines[j++];
p = total_lines+i; //point to the start of the next line
i++;
while(i < MAX_CHARS && (total_lines[i++] = lines[j++]))
;
if (i == MAX_CHARS)
return -1;
return 1;
}顺便说一下,当我试图将p传递到the variable p is being used without being initialized时,VS给了我错误消息copy_lines,所以我将它初始化为零。我为什么不能先把它设为零就不能通过它呢?
这是完整的代码,如果有人需要的话。
#include <stdio.h>
#include <string.h>
#define MAXLINES 5000
#define MAX_CHARS 50000
char *lineptr[MAXLINES];
int readlines (char *lineptr[], int nlines, char total_lines[], int max_chars);
void writelines (char *lineptr[], int nlines);
void qsort(char *lineptr[], int left, int right);
int main()
{
int nlines;
char total_lines[MAX_CHARS];
if((nlines = readlines (lineptr, MAXLINES, total_lines, MAX_CHARS)) >= 0){
qsort (lineptr, 0, nlines-1);
writelines(lineptr, nlines);
getch();
return 0;
}
else{
printf("error: input too big to sort\n");
return -1;
}
}
#define MAXLEN 1000
int getline (char *, int);
char *alloc(int);
int copy_lines(char total_lines[], char line[], char *p);
int readlines (char *lineptr[], int maxlines, char total_lines[], int max_chars)
{
int len, nlines;
char *p, line[MAXLEN];
p = 0;
nlines = 0;
while((len = getline(line, MAXLEN)) > 0)
if (nlines >= maxlines)
return -1;
else{
line [len-1] = '\0';
copy_lines(total_lines, line, p);
//strcpy(p, line);
lineptr[nlines++] = p;
printf("%s\n", lineptr);
}
return nlines;
}
int copy_lines(char total_lines[], char lines[], char *p)
{
static int i = 0;
int j = 0;
total_lines[i] = lines[j++];
p = total_lines+i; //point to the start of the next line
i++;
while(i < MAX_CHARS && (total_lines[i++] = lines[j++]))
;
if (i == MAX_CHARS)
return -1;
return 1;
}
void writelines (char *lineptr[], int nlines)
{
int i;
for(i = 0; i < nlines; i++)
printf("%s\n", lineptr[i]);
}
void qsort(char *v[], int left, int right)
{
int i, last;
void swap (char *v[], int i, int j);
if (left >= right)
return;
swap (v, left, (left + right)/2);
last = left;
for (i = left + 1; i <= right; i++)
if (strcmp (v[i], v[left]) < 0)
swap (v, ++last, i);
swap (v, left, last);
qsort(v, left, last-1);
qsort(v, last+1, right);
}
void swap (char *v[], int i, int j)
{
char *temp;
temp = v[i];
v[i] = v[j];
v[j] = temp;
}
#define ALLOCSIZE 10000
static char allocbuf[ALLOCSIZE];
static char *allocp = allocbuf;
char *alloc(int n)
{
if (allocbuf + ALLOCSIZE - allocp >= n){
allocp += n;
return allocp - n;
}
else
return 0;
}
int getline(char *s, int lim) // returns length of string if string size < buffer limit-2 (MAXLINE-2), else string length is incorrect
{
int i, c;
for (i = 0; i < lim - 2 && (c = getchar()) != EOF && c != '\n'; i++)
*s++ = c;
if (c == '\n'){
*s++ = c;
i++;
}
*s = '\0';
return i;
}发布于 2014-09-05 04:01:54
您不能重新定义int getline (char *, int);。libc已经包含了一个getline函数。(参见man getline)是否在启用警告的情况下进行编译?尝试使用-Wall -Wextra进行编译。将getline重命名为getline2或其他东西,以避免与stdio.h中以前的getline声明发生冲突。
正如所指出的那样,由于getline在技术上不是一个保留字,所以它必须可以由符合ISO的实现重新定义。然而,正如所指出的那样,许多non-conforming C实现都是non-conforming,不会允许这种重新定义。
发布于 2014-09-05 05:29:56
变量在C中通过值传递,copy_lines中的变量copy_lines与readlines中的p是不同的变量。当函数被调用时,前者被创建并用后者的值进行初始化。您可以通过对每个变量使用不同的名称来消除一些混淆。
若要允许一个函数将局部变量修改为另一个函数,则必须传递指向该变量的指针。指向char *的指针具有char **类型。
https://stackoverflow.com/questions/25678377
复制相似问题