我正在嘗試制作一個模擬 ls 命令的程式,然后按不區分大小寫的字母順序對檔案進行排序。到目前為止,所有的檔案名都進入了 words 陣列,但是當我嘗試編譯時,出現了問題。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <dirent.h>
// This program is pretty much a simulation of the ls command. Find out how to scan all of the files
// in the directory it's being run in and print out all the file names. Has to be in order.
int main(int argc, char* argv[])
{
char **words = calloc(1000, sizeof(*words));
char **words2 = calloc(1000, sizeof(*words2));
DIR *d;
struct dirent *dir; // Pointer for directory entry
d = opendir(".");
char* a = ".";
char* b = "..";
char* c = "ls";
int ret1, ret2, ret3, count = 0;
if (d) // opendir returns NULL if couldn't open directory
{
while ((dir = readdir(d)) != NULL)
{
ret1 = strcmp(dir->d_name, a); // Compare with the parent directory.
ret2 = strcmp(dir->d_name, b); // Compare with the parent directory.
ret3 = strcmp(dir->d_name, c); // Compare with the ls
if (ret1 == 0 || ret2 == 0 || ret3 == 0)
{
// Skip the ., .., and ls
}
else
{
words[count] = dir->d_name; // Put the file name in the array.
count ;
}
}
for (int i = 1; i < 10; i ) // Start readjusting the array in alphabetical order.
{
for (int j = 1; j < 10; j )
{
if (strcmp(words[j - 1], words[j]) > 0)
{
strcpy(words2, words[j - 1]);
strcpy(words[j - 1], words[j]);
strcpy(words[j], words2);
}
}
}
// Print every word in the array.
while (count != 0)
{
printf("%s\n", words[count - 1]);
count--;
}
}
// Closing and freeing
closedir(d);
for (int a = 0; a < 1000; a)
{
free(words[a]);
}
for (int a = 0; a < 1000; a)
{
free(words2[a]);
}
free(words);
free(words2);
return 0;
}
當我編譯時,這是我在下面得到的錯誤訊息。當我嘗試對陣列進行排序時,它發生在序列中。我能做些什么來解決這個問題嗎?
ls.c: In function ‘main’:
ls.c:52:13: warning: passing argument 1 of ‘strcpy’ from incompatible pointer type [-Wincompatible-pointer-types]
52 | strcpy(words2, words[j - 1]);
| ^~~~~~
| |
| char **
In file included from ls.c:3:
/usr/include/string.h:122:14: note: expected ‘char * restrict’ but argument is of type ‘char **’
122 | extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
| ^~~~~~
ls.c:54:23: warning: passing argument 2 of ‘strcpy’ from incompatible pointer type [-Wincompatible-pointer-types]
54 | strcpy(words[j], words2);
| ^~~~~~
| |
| char **
In file included from ls.c:3:
/usr/include/string.h:122:14: note: expected ‘const char * restrict’ but argument is of type ‘char **’
122 | extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
| ^~~~~~
uj5u.com熱心網友回復:
在此 if 陳述句中 strcpy 的呼叫中
if (strcmp(words[j - 1], words[j]) > 0)
{
strcpy(words2, words[j - 1]);
strcpy(words[j - 1], words[j]);
strcpy(words[j], words2);
}
引數 words 和 words2 具有型別,char **但函式需要型別的引數char *。
char **words = calloc(1000, sizeof(*words));
char **words2 = calloc(1000, sizeof(*words2));
似乎該變數words2被用作存盤字串的臨時變數。在這種情況下,它應該用型別宣告char *并且足夠大以存盤指標指向的動態分配陣列中的指標指向的任何字串words。
也不清楚為什么在 for 回圈中使用幻數10而不是變數count,例如
for (int i = 1; i < 10; i )
注意比較函式strcmp區分大小寫。
uj5u.com熱心網友回復:
來自莫斯科的弗拉德的回答完全切中要害。讓我補充一點,您的代碼中還有另一個非常討厭的錯誤:結構的d_name欄位DIR不是新分配的,因此您確實需要分配名稱并將其復制到words序列中:
words[count] = strdup(dir->d_name); // Put the file name in the array.
此外,這count對您的序列非常重要。使用它進行排序并且在列印陣列內容時不要亂動它:
// Print every word in the array.
for (int i = 0; i < count; i) {
printf("%s\n", words[i]);
}
最后,您假設所有words的長度都相同,但這是不對的。所以你想要交換的是指標,而不是它們指向的字符。如果你想要一個易于實作的排序,使用選擇排序:它和冒泡排序一樣慢,但交換更少。順便說一句,你的冒泡排序是錯誤的,因為你沒有跟蹤交換,所以你失去了冒泡排序的唯一優勢,那就是提前停止。在您的情況下,選擇排序的可能實作可能是:
for (int i = 0; i < count; i) {
int imin = i;
for (int j = i 1; j < count; j) {
if (strcmp(words[j], words[imin]) < 0) {
imin = j;
}
}
char *tmp = words[i];
words[i] = words[imin];
words[imin] = tmp;
}
然后,不要再使用words2了,最多只能免費使用count。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/314597.html
上一篇:如何訂購資料驗證串列
下一篇:合并排序演算法不適用于大型資料集
